phanerozoic commited on
Commit
e4a7311
·
verified ·
1 Parent(s): bcadfc2

Rename from tiny-FullAdder-verified

Browse files
Files changed (4) hide show
  1. README.md +107 -0
  2. config.json +23 -0
  3. model.py +75 -0
  4. model.safetensors +3 -0
README.md ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - pytorch
5
+ - safetensors
6
+ - threshold-logic
7
+ - neuromorphic
8
+ - arithmetic
9
+ ---
10
+
11
+ # threshold-fulladder
12
+
13
+ Adds three 1-bit inputs (a, b, carry_in), producing sum and carry_out. The core of ripple-carry adders.
14
+
15
+ ## Circuit
16
+
17
+ ```
18
+ a b
19
+ │ │
20
+ └───┬───┘
21
+
22
+ ┌─────────┐
23
+ │ HA1 │ First half adder
24
+ └─────────┘
25
+ │ │
26
+ s1 c1
27
+ │ \
28
+ │ cin \
29
+ └──┬──┘ \
30
+ ▼ \
31
+ ┌─────────┐ \
32
+ │ HA2 │ │
33
+ └─────────┘ │
34
+ │ │ │
35
+ sum c2 │
36
+ │ │
37
+ └──┬───┘
38
+
39
+ ┌──────┐
40
+ │ OR │
41
+ └──────┘
42
+
43
+
44
+ cout
45
+ ```
46
+
47
+ ## Truth Table
48
+
49
+ | a | b | cin | sum | cout |
50
+ |---|---|-----|-----|------|
51
+ | 0 | 0 | 0 | 0 | 0 |
52
+ | 0 | 0 | 1 | 1 | 0 |
53
+ | 0 | 1 | 0 | 1 | 0 |
54
+ | 0 | 1 | 1 | 0 | 1 |
55
+ | 1 | 0 | 0 | 1 | 0 |
56
+ | 1 | 0 | 1 | 0 | 1 |
57
+ | 1 | 1 | 0 | 0 | 1 |
58
+ | 1 | 1 | 1 | 1 | 1 |
59
+
60
+ Binary: a + b + cin = (cout × 2) + sum
61
+
62
+ ## Architecture
63
+
64
+ | Component | Neurons |
65
+ |-----------|---------|
66
+ | HA1 (a + b) | 4 |
67
+ | HA2 (s1 + cin) | 4 |
68
+ | OR (c1, c2) | 1 |
69
+
70
+ **Total: 9 neurons, 21 parameters, 4 layers**
71
+
72
+ ## Composition
73
+
74
+ ```
75
+ s1, c1 = HalfAdder(a, b)
76
+ sum, c2 = HalfAdder(s1, cin)
77
+ cout = OR(c1, c2)
78
+ ```
79
+
80
+ A carry propagates if either half adder produces one.
81
+
82
+ ## Usage
83
+
84
+ ```python
85
+ from safetensors.torch import load_file
86
+
87
+ w = load_file('model.safetensors')
88
+
89
+ def full_adder(a, b, cin):
90
+ # Implementation uses two half adders + OR
91
+ # See model.py for full implementation
92
+ pass
93
+ ```
94
+
95
+ ## Files
96
+
97
+ ```
98
+ threshold-fulladder/
99
+ ├── model.safetensors
100
+ ├── model.py
101
+ ├── config.json
102
+ └── README.md
103
+ ```
104
+
105
+ ## License
106
+
107
+ MIT
config.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model_type": "threshold_network",
3
+ "task": "full_adder",
4
+ "architecture": "3 -> (HA1 + HA2 + OR)",
5
+ "input_size": 3,
6
+ "inputs": ["a", "b", "cin"],
7
+ "outputs": ["sum", "cout"],
8
+ "num_neurons": 9,
9
+ "num_parameters": 21,
10
+ "depth": 4,
11
+ "activation": "heaviside",
12
+ "weight_constraints": "integer",
13
+ "verification": {
14
+ "method": "coq_proof",
15
+ "exhaustive": true,
16
+ "inputs_tested": 8
17
+ },
18
+ "accuracy": {
19
+ "all_inputs": "8/8",
20
+ "percentage": 100.0
21
+ },
22
+ "github": "https://github.com/CharlesCNorton/coq-circuits"
23
+ }
model.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Threshold Network for Full Adder
3
+
4
+ Adds three 1-bit inputs (a, b, cin), producing sum and carry outputs.
5
+ Built from two half adders and an OR gate.
6
+ """
7
+
8
+ import torch
9
+ from safetensors.torch import load_file
10
+
11
+
12
+ def heaviside(x):
13
+ return (x >= 0).float()
14
+
15
+
16
+ class ThresholdFullAdder:
17
+ """
18
+ Full adder: sum = a XOR b XOR cin, cout = (a AND b) OR ((a XOR b) AND cin)
19
+ """
20
+
21
+ def __init__(self, weights_dict):
22
+ self.weights = weights_dict
23
+
24
+ def half_adder(self, prefix, a, b):
25
+ inputs = torch.tensor([float(a), float(b)])
26
+
27
+ # XOR for sum
28
+ or_out = heaviside((inputs * self.weights[f'{prefix}.sum.layer1.or.weight']).sum() +
29
+ self.weights[f'{prefix}.sum.layer1.or.bias'])
30
+ nand_out = heaviside((inputs * self.weights[f'{prefix}.sum.layer1.nand.weight']).sum() +
31
+ self.weights[f'{prefix}.sum.layer1.nand.bias'])
32
+ layer1 = torch.tensor([or_out, nand_out])
33
+ sum_out = heaviside((layer1 * self.weights[f'{prefix}.sum.layer2.weight']).sum() +
34
+ self.weights[f'{prefix}.sum.layer2.bias'])
35
+
36
+ # AND for carry
37
+ carry_out = heaviside((inputs * self.weights[f'{prefix}.carry.weight']).sum() +
38
+ self.weights[f'{prefix}.carry.bias'])
39
+
40
+ return int(sum_out.item()), int(carry_out.item())
41
+
42
+ def __call__(self, a, b, cin):
43
+ # First half adder: a + b
44
+ s1, c1 = self.half_adder('ha1', a, b)
45
+
46
+ # Second half adder: s1 + cin
47
+ sum_out, c2 = self.half_adder('ha2', s1, cin)
48
+
49
+ # Carry out = c1 OR c2
50
+ carry_inputs = torch.tensor([float(c1), float(c2)])
51
+ cout = heaviside((carry_inputs * self.weights['carry_or.weight']).sum() +
52
+ self.weights['carry_or.bias'])
53
+
54
+ return int(sum_out), int(cout.item())
55
+
56
+ @classmethod
57
+ def from_safetensors(cls, path="model.safetensors"):
58
+ return cls(load_file(path))
59
+
60
+
61
+ if __name__ == "__main__":
62
+ model = ThresholdFullAdder.from_safetensors("model.safetensors")
63
+
64
+ print("Full Adder Truth Table:")
65
+ print("-" * 40)
66
+ print("a | b | cin | sum | cout")
67
+ print("-" * 40)
68
+ for a in [0, 1]:
69
+ for b in [0, 1]:
70
+ for cin in [0, 1]:
71
+ s, cout = model(a, b, cin)
72
+ expected_sum = (a + b + cin) % 2
73
+ expected_cout = (a + b + cin) // 2
74
+ status = "OK" if (s == expected_sum and cout == expected_cout) else "FAIL"
75
+ print(f"{a} | {b} | {cin} | {s} | {cout} [{status}]")
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:33c256206b93b37c9757e6c3cac3bbf3868f6995021b2872e812885719513651
3
+ size 1452