File size: 4,177 Bytes
2a0195d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
---

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