phanerozoic commited on
Commit
2a0195d
Β·
verified Β·
1 Parent(s): c879de4

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. README.md +155 -0
  2. config.json +9 -0
  3. model.py +36 -0
  4. model.safetensors +3 -0
README.md ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - pytorch
5
+ - safetensors
6
+ - threshold-logic
7
+ - neuromorphic
8
+ - arithmetic
9
+ ---
10
+
11
+ # threshold-fullsubtractor
12
+
13
+ Subtracts three 1-bit inputs (a, b, borrow_in), producing difference and borrow_out. The subtraction counterpart to the full adder.
14
+
15
+ ## Circuit
16
+
17
+ ```
18
+ a b
19
+ β”‚ β”‚
20
+ β””β”€β”€β”€β”¬β”€β”€β”€β”˜
21
+ β–Ό
22
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
23
+ β”‚ HS1 β”‚ First half subtractor
24
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
25
+ β”‚ β”‚
26
+ d1 b1
27
+ β”‚ \
28
+ β”‚ bin \
29
+ β””β”€β”€β”¬β”€β”€β”˜ \
30
+ β–Ό \
31
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” \
32
+ β”‚ HS2 β”‚ β”‚
33
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
34
+ β”‚ β”‚ β”‚
35
+ diff b2 β”‚
36
+ β”‚ β”‚
37
+ β””β”€β”€β”¬β”€β”€β”€β”˜
38
+ β–Ό
39
+ β”Œβ”€β”€β”€β”€β”€β”€β”
40
+ β”‚ OR β”‚
41
+ β””β”€β”€β”€β”€β”€β”€β”˜
42
+ β”‚
43
+ β–Ό
44
+ bout
45
+ ```
46
+
47
+ ## Half Subtractor Detail
48
+
49
+ ```
50
+ x y
51
+ β”‚ β”‚
52
+ β”œβ”€β”€β”€β”¬β”€β”€β”€β”€
53
+ β”‚ β”‚ β”‚
54
+ β–Ό β”‚ β–Ό
55
+ β”Œβ”€β”€β”€β”€β”€β”€β”β”‚β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”
56
+ β”‚ OR β”‚β”‚β”‚ NAND β”‚ β”‚ Β¬x ∧ yβ”‚
57
+ β”‚w:1,1 β”‚β”‚β”‚w:-1,-1β”‚ β”‚w:-1,1 β”‚
58
+ β”‚b: -1 β”‚β”‚β”‚b: +1 β”‚ β”‚b: -1 β”‚
59
+ β””β”€β”€β”€β”€β”€β”€β”˜β”‚β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”˜
60
+ β”‚ β”‚ β”‚ β”‚
61
+ β””β”€β”€β”€β”Όβ”€β”€β”€β”˜ β”‚
62
+ β–Ό β”‚
63
+ β”Œβ”€β”€β”€β”€β”€β”€β” β”‚
64
+ β”‚ AND β”‚ β”‚
65
+ β””β”€β”€β”€β”€β”€β”€β”˜ β”‚
66
+ β”‚ β”‚
67
+ β–Ό β–Ό
68
+ diff borrow
69
+ ```
70
+
71
+ ## Truth Table
72
+
73
+ | a | b | bin | diff | bout |
74
+ |---|---|-----|------|------|
75
+ | 0 | 0 | 0 | 0 | 0 |
76
+ | 0 | 0 | 1 | 1 | 1 |
77
+ | 0 | 1 | 0 | 1 | 1 |
78
+ | 0 | 1 | 1 | 0 | 1 |
79
+ | 1 | 0 | 0 | 1 | 0 |
80
+ | 1 | 0 | 1 | 0 | 0 |
81
+ | 1 | 1 | 0 | 0 | 0 |
82
+ | 1 | 1 | 1 | 1 | 1 |
83
+
84
+ Binary: a - b - bin = diff - (bout Γ— 2)
85
+
86
+ ## Composition
87
+
88
+ ```
89
+ d1, b1 = HalfSubtractor(a, b)
90
+ diff, b2 = HalfSubtractor(d1, bin)
91
+ bout = OR(b1, b2)
92
+ ```
93
+
94
+ A borrow propagates if either half subtractor produces one.
95
+
96
+ ## Architecture
97
+
98
+ | Component | Neurons |
99
+ |-----------|---------|
100
+ | HS1 (a - b) | 4 |
101
+ | HS2 (d1 - bin) | 4 |
102
+ | OR (b1, b2) | 1 |
103
+
104
+ **Total: 9 neurons, 27 parameters, 4 layers**
105
+
106
+ ## Contrast with Full Adder
107
+
108
+ | Circuit | Carry/Borrow | HS function |
109
+ |---------|--------------|-------------|
110
+ | FullAdder | cout = OR(c1, c2) | c = a AND b |
111
+ | FullSubtractor | bout = OR(b1, b2) | b = NOT(a) AND b |
112
+
113
+ The only structural difference: the borrow circuit uses NOT(a) AND b instead of AND.
114
+
115
+ ## Usage
116
+
117
+ ```python
118
+ from safetensors.torch import load_file
119
+ import torch
120
+
121
+ w = load_file('model.safetensors')
122
+
123
+ def full_subtractor(a, b, bin_in):
124
+ inp = torch.tensor([float(a), float(b)])
125
+
126
+ # HS1
127
+ hs1_l1 = (inp @ w['hs1.xor.layer1.weight'].T + w['hs1.xor.layer1.bias'] >= 0).float()
128
+ d1 = (hs1_l1 @ w['hs1.xor.layer2.weight'].T + w['hs1.xor.layer2.bias'] >= 0).float().item()
129
+ b1 = (inp @ w['hs1.borrow.weight'].T + w['hs1.borrow.bias'] >= 0).float().item()
130
+
131
+ # HS2
132
+ inp2 = torch.tensor([d1, float(bin_in)])
133
+ hs2_l1 = (inp2 @ w['hs2.xor.layer1.weight'].T + w['hs2.xor.layer1.bias'] >= 0).float()
134
+ diff = int((hs2_l1 @ w['hs2.xor.layer2.weight'].T + w['hs2.xor.layer2.bias'] >= 0).item())
135
+ b2 = (inp2 @ w['hs2.borrow.weight'].T + w['hs2.borrow.bias'] >= 0).float().item()
136
+
137
+ # Final borrow
138
+ bout = int((torch.tensor([b1, b2]) @ w['bout.weight'].T + w['bout.bias'] >= 0).item())
139
+
140
+ return diff, bout
141
+ ```
142
+
143
+ ## Files
144
+
145
+ ```
146
+ threshold-fullsubtractor/
147
+ β”œβ”€β”€ model.safetensors
148
+ β”œβ”€β”€ model.py
149
+ β”œβ”€β”€ config.json
150
+ └── README.md
151
+ ```
152
+
153
+ ## License
154
+
155
+ MIT
config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "threshold-fullsubtractor",
3
+ "description": "Full subtractor as threshold circuit",
4
+ "inputs": 3,
5
+ "outputs": 2,
6
+ "neurons": 9,
7
+ "layers": 4,
8
+ "parameters": 27
9
+ }
model.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import load_file
3
+
4
+ def load_model(path='model.safetensors'):
5
+ return load_file(path)
6
+
7
+ def full_subtractor(a, b, bin_in, weights):
8
+ """Full subtractor: computes a - b - bin, returns (diff, borrow_out)"""
9
+ inp = torch.tensor([float(a), float(b)])
10
+
11
+ # HS1: a - b -> d1, b1
12
+ hs1_l1 = (inp @ weights['hs1.xor.layer1.weight'].T + weights['hs1.xor.layer1.bias'] >= 0).float()
13
+ d1 = (hs1_l1 @ weights['hs1.xor.layer2.weight'].T + weights['hs1.xor.layer2.bias'] >= 0).float().item()
14
+ b1 = (inp @ weights['hs1.borrow.weight'].T + weights['hs1.borrow.bias'] >= 0).float().item()
15
+
16
+ # HS2: d1 - bin -> diff, b2
17
+ inp2 = torch.tensor([d1, float(bin_in)])
18
+ hs2_l1 = (inp2 @ weights['hs2.xor.layer1.weight'].T + weights['hs2.xor.layer1.bias'] >= 0).float()
19
+ diff = int((hs2_l1 @ weights['hs2.xor.layer2.weight'].T + weights['hs2.xor.layer2.bias'] >= 0).item())
20
+ b2 = (inp2 @ weights['hs2.borrow.weight'].T + weights['hs2.borrow.bias'] >= 0).float().item()
21
+
22
+ # Final borrow: OR(b1, b2)
23
+ bout_inp = torch.tensor([b1, b2])
24
+ bout = int((bout_inp @ weights['bout.weight'].T + weights['bout.bias'] >= 0).item())
25
+
26
+ return diff, bout
27
+
28
+ if __name__ == '__main__':
29
+ w = load_model()
30
+ print('FullSubtractor truth table:')
31
+ print('a b bin | diff bout')
32
+ for a in [0, 1]:
33
+ for b in [0, 1]:
34
+ for bin_in in [0, 1]:
35
+ diff, bout = full_subtractor(a, b, bin_in, w)
36
+ print(f'{a} {b} {bin_in} | {diff} {bout}')
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:849e141847cebebc05e4f2a72e2cf47f350e00890cc2c816baaacacb9c2488cb
3
+ size 1132