--- license: mit tags: - pytorch - safetensors - threshold-logic - neuromorphic - arithmetic --- # threshold-fullsubtractor Subtracts three 1-bit inputs (a, b, borrow_in), producing difference and borrow_out. The subtraction counterpart to the full adder. ## Circuit ``` a b │ │ └───┬───┘ ▼ ┌─────────┐ │ HS1 │ First half subtractor └─────────┘ │ │ d1 b1 │ \ │ bin \ └──┬──┘ \ ▼ \ ┌─────────┐ \ │ HS2 │ │ └─────────┘ │ │ │ │ diff b2 │ │ │ └──┬───┘ ▼ ┌──────┐ │ OR │ └──────┘ │ ▼ bout ``` ## Half Subtractor Detail ``` x y │ │ ├───┬───┤ │ │ │ ▼ │ ▼ ┌──────┐│┌──────┐ ┌───────┐ │ OR │││ NAND │ │ ¬x ∧ y│ │w:1,1 │││w:-1,-1│ │w:-1,1 │ │b: -1 │││b: +1 │ │b: -1 │ └──────┘│└──────┘ └───────┘ │ │ │ │ └───┼───┘ │ ▼ │ ┌──────┐ │ │ AND │ │ └──────┘ │ │ │ ▼ ▼ diff borrow ``` ## Truth Table | a | b | bin | diff | bout | |---|---|-----|------|------| | 0 | 0 | 0 | 0 | 0 | | 0 | 0 | 1 | 1 | 1 | | 0 | 1 | 0 | 1 | 1 | | 0 | 1 | 1 | 0 | 1 | | 1 | 0 | 0 | 1 | 0 | | 1 | 0 | 1 | 0 | 0 | | 1 | 1 | 0 | 0 | 0 | | 1 | 1 | 1 | 1 | 1 | Binary: a - b - bin = diff - (bout × 2) ## Composition ``` d1, b1 = HalfSubtractor(a, b) diff, b2 = HalfSubtractor(d1, bin) bout = OR(b1, b2) ``` A borrow propagates if either half subtractor produces one. ## Architecture | Component | Neurons | |-----------|---------| | HS1 (a - b) | 4 | | HS2 (d1 - bin) | 4 | | OR (b1, b2) | 1 | **Total: 9 neurons, 27 parameters, 4 layers** ## Contrast with Full Adder | Circuit | Carry/Borrow | HS function | |---------|--------------|-------------| | FullAdder | cout = OR(c1, c2) | c = a AND b | | FullSubtractor | bout = OR(b1, b2) | b = NOT(a) AND b | The only structural difference: the borrow circuit uses NOT(a) AND b instead of AND. ## Usage ```python from safetensors.torch import load_file import torch w = load_file('model.safetensors') def full_subtractor(a, b, bin_in): inp = torch.tensor([float(a), float(b)]) # HS1 hs1_l1 = (inp @ w['hs1.xor.layer1.weight'].T + w['hs1.xor.layer1.bias'] >= 0).float() d1 = (hs1_l1 @ w['hs1.xor.layer2.weight'].T + w['hs1.xor.layer2.bias'] >= 0).float().item() b1 = (inp @ w['hs1.borrow.weight'].T + w['hs1.borrow.bias'] >= 0).float().item() # HS2 inp2 = torch.tensor([d1, float(bin_in)]) hs2_l1 = (inp2 @ w['hs2.xor.layer1.weight'].T + w['hs2.xor.layer1.bias'] >= 0).float() diff = int((hs2_l1 @ w['hs2.xor.layer2.weight'].T + w['hs2.xor.layer2.bias'] >= 0).item()) b2 = (inp2 @ w['hs2.borrow.weight'].T + w['hs2.borrow.bias'] >= 0).float().item() # Final borrow bout = int((torch.tensor([b1, b2]) @ w['bout.weight'].T + w['bout.bias'] >= 0).item()) return diff, bout ``` ## Files ``` threshold-fullsubtractor/ ├── model.safetensors ├── model.py ├── config.json └── README.md ``` ## License MIT