-
Notifications
You must be signed in to change notification settings - Fork 0
/
BoolNat.agda
207 lines (157 loc) · 7.54 KB
/
BoolNat.agda
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
module BoolNat where
open import BaseLogic
open import Data.Bool
open import Data.Bool.Operations
open import Data.False
open import Data.Nat
import Data.Nat.Operations
open import Data.List using ( List ; [])
open import Data.List.Operations
open import Data.Maybe
open import Data.Product
open import Data.PropositionalEquality
open import Data.Vector using (Vector ; [])
import Data.Vector.Operations
open import Functions
open import ListVector
BinaryNat : Set
BinaryNat = List Bool
BitVector : (n : Nat) → Set
BitVector n = Vector Bool n
Bool2Nat : Bool → Nat
Bool2Nat false = zero
Bool2Nat true = suc zero
Binary2Unary-helper : BinaryNat → Maybe Nat → Maybe Nat
Binary2Unary-helper [] Nothing = Nothing
Binary2Unary-helper [] (Just acc) = Just acc
Binary2Unary-helper (Data.List._∷_ a as) Nothing = Binary2Unary-helper as (Just (Bool2Nat a))
Binary2Unary-helper (Data.List._∷_ a as) (Just acc) = Binary2Unary-helper as (Just (Data.Nat.Operations._+_ (Data.Nat.Operations._*_ (Data.Nat.Operations._^_ 2 (length (Data.List._∷_ a as))) (Bool2Nat a)) acc))
Binary2Unary : BinaryNat → Maybe Nat
Binary2Unary n = Binary2Unary-helper n Nothing
BitVector2Unary-helper : {n : Nat} → BitVector n → Maybe Nat → Maybe Nat
BitVector2Unary-helper {zero} [] Nothing = Nothing
BitVector2Unary-helper {zero} [] (Just acc) = Just acc
BitVector2Unary-helper {suc n} (Data.Vector._∷_ a as) Nothing = BitVector2Unary-helper {n} as (Just (Bool2Nat a))
BitVector2Unary-helper {suc n} (Data.Vector._∷_ a as) (Just acc) = BitVector2Unary-helper {n} as (Just (Data.Nat.Operations._+_ (Data.Nat.Operations._*_ (Data.Nat.Operations._^_ 2 (suc n)) (Bool2Nat a)) acc))
BitVector2Unary : {n : Nat} → BitVector n → Maybe Nat
BitVector2Unary v = BitVector2Unary-helper v Nothing
first-nonzero : BinaryNat → Maybe Nat
first-nonzero [] = Nothing
first-nonzero (Data.List._∷_ false rest) = first-nonzero rest
first-nonzero (Data.List._∷_ true rest) = Just (length (Data.List._∷_ true rest))
first-digit : BinaryNat → Maybe Bool
first-digit [] = Nothing
first-digit (Data.List._∷_ a as) = Just a
last-digit : BinaryNat → Maybe Bool
last-digit [] = Nothing
last-digit (Data.List._∷_ a []) = Just a
last-digit (Data.List._∷_ a1 (Data.List._∷_ a2 as)) = last-digit (Data.List._∷_ a2 as)
first-nonzero-vec : {n : Nat} → BitVector n → Maybe Nat
first-nonzero-vec {zero} [] = Nothing
first-nonzero-vec {suc n} (Data.Vector._∷_ false rest) = first-nonzero-vec {n} rest
first-nonzero-vec {suc n} (Data.Vector._∷_ true rest) = Just n
first-digit-vec : {n : Nat} → BitVector n → Maybe Bool
first-digit-vec [] = Nothing
first-digit-vec (Data.Vector._∷_ a as) = Just a
first-digit-nevec : {n : Nat} → BitVector (suc n) → Bool
first-digit-nevec {zero} (Data.Vector._∷_ a []) = a
first-digit-nevec {suc n} (Data.Vector._∷_ a1 (Data.Vector._∷_ a2 as)) = a1
last-digit-vec : {n : Nat} → BitVector n → Maybe Bool
last-digit-vec {zero} [] = Nothing
last-digit-vec {suc zero} (Data.Vector._∷_ a []) = Just a
last-digit-vec {suc (suc n)} (Data.Vector._∷_ a1 (Data.Vector._∷_ a2 as)) = last-digit-vec (Data.Vector._∷_ a2 as)
last-digit-nevec : {n : Nat} → BitVector (suc n) → Bool
last-digit-nevec {zero} (Data.Vector._∷_ a []) = a
last-digit-nevec {suc n} (Data.Vector._∷_ a1 (Data.Vector._∷_ a2 as)) = last-digit-nevec {n} (Data.Vector._∷_ a2 as)
bit-add-direct : Bool → Bool → Bool
bit-add-direct false false = false
bit-add-direct false true = true
bit-add-direct true false = true
bit-add-direct true true = false
bit-add-direct' : Bool → Bool → Bool
bit-add-direct' b1 b2 = b1 xor b2
bit-add-carry : Bool → Bool → Bool
bit-add-carry false false = false
bit-add-carry false true = false
bit-add-carry true false = false
bit-add-carry true true = true
bit-add-carry' : Bool → Bool → Bool
bit-add-carry' b1 b2 = b1 and b2
bit-add-with-carry : Bool → Bool → Bool × Bool
bit-add-with-carry b1 b2 = (bit-add-direct b1 b2 , bit-add-carry b1 b2)
bit-add-half : Bool → Bool → Bool × Bool
bit-add-half b1 b2 = (bit-add-direct b1 b2 , bit-add-carry b1 b2)
bit-add-half' : Bool → Bool → Bool × Bool
bit-add-half' b1 b2 = ((b1 xor b2) , (b1 and b2))
bit-add-full : Bool → Bool → Bool → Bool × Bool
bit-add-full b1 b2 c = (o1 , o2)
where
t1 : Bool
t1 = bit-add-direct b1 b2
c1 : Bool
c1 = bit-add-carry b1 b2
o1 : Bool
o1 = bit-add-direct t1 c
c2 : Bool
c2 = bit-add-carry t1 c
o2 : Bool
o2 = bit-add-direct c1 c2
bit-add-full' : Bool → Bool → Bool → Bool × Bool
bit-add-full' b1 b2 c = (o1 , o2)
where
t1 = b1 xor b2
c1 = b1 and b2
o1 = t1 xor c
c2 = t1 and c
o2 = c1 xor c2
{-
bit-adder-adj : BinaryNat → BinaryNat → BinaryNat → BinaryNat → Maybe BinaryNat
bit-adder-adj [] l-acc r r-acc
bit-adder : BinaryNat → BinaryNat → Maybe BinaryNat
bit-adder [] n = Nothing
bit-adder n [] = Nothing
bit-adder (b ∷ bs) (c ∷ cs) =
-}
{-
bit-adder-part : BinaryNat → BinaryNat → List (Bool × Bool)
bit-adder-part l1 l2 =
-}
bitvector-adder-part1 : {n : Nat} → BitVector n → BitVector n → Vector (Bool × Bool) n
bitvector-adder-part1 {n} v1 v2 = Data.Vector.Operations.map (uncurry bit-add-half) (Data.Vector.Operations.zip v1 v2)
maybe-suc : Nat → Nat
maybe-suc 0 = 0
maybe-suc (suc n) = (suc (suc n))
{-
bitvector-adder-part2 : {n : Nat} → Vector (Bool × Bool) n → BitVector (maybe-suc n)
bitvector-adder-part2 {n} v
-}
pad-zeroes' : BinaryNat → Nat → BinaryNat
pad-zeroes' [] zero = []
pad-zeroes' [] (suc n) = (Data.List._∷_ false (pad-zeroes' [] n))
pad-zeroes' (Data.List._∷_ a as) zero = (Data.List._∷_ a (pad-zeroes' as zero))
pad-zeroes' (Data.List._∷_ a as) (suc n) = (Data.List._∷_ a (pad-zeroes' as n))
pad-zeroes : BinaryNat → Nat → BinaryNat
pad-zeroes b n = pad-zeroes' (reverse b) n
strip-leading-zeroes : BinaryNat → BinaryNat
strip-leading-zeroes [] = []
strip-leading-zeroes (Data.List._∷_ false rest) = strip-leading-zeroes rest
strip-leading-zeroes (Data.List._∷_ true rest) = (Data.List._∷_ true rest)
strip-leading-zeroes-vec : {n : Nat} → (v : BitVector n) → BitVector (length (strip-leading-zeroes (vector2list v)))
strip-leading-zeroes-vec {n} v = list2vector (strip-leading-zeroes (vector2list v))
bitvector-adder' : {n : Nat} → BitVector n → BitVector n → BitVector (maybe-suc n)
bitvector-adder' {zero} [] [] = []
bitvector-adder' {suc zero} (Data.Vector._∷_ a []) (Data.Vector._∷_ b []) = Data.Vector._∷_ (second (bit-add-full a b false)) (Data.Vector._∷_ (first (bit-add-full a b false)) [])
bitvector-adder' {suc (suc n)} (Data.Vector._∷_ a1 (Data.Vector._∷_ a2 as)) (Data.Vector._∷_ b1 (Data.Vector._∷_ b2 bs)) =
Data.Vector._∷_ (second (bit-add-full a1 b1 (Data.Vector.Operations.nevec-head (bitvector-adder' {suc n} (Data.Vector._∷_ a2 as) (Data.Vector._∷_ b2 bs)))))
(Data.Vector._∷_ (first (bit-add-full a1 b1 (Data.Vector.Operations.nevec-head (bitvector-adder' {suc n} (Data.Vector._∷_ a2 as) (Data.Vector._∷_ b2 bs)))))
(Data.Vector.Operations.nevec-tail (bitvector-adder' {suc n} (Data.Vector._∷_ a2 as) (Data.Vector._∷_ b2 bs))))
{-
Now need to prove the correctness of this bit-adder.
-}
bitvector-adder : {n : Nat} → (v1 : BitVector n) → (v2 : BitVector n) → BitVector (length (strip-leading-zeroes (vector2list (bitvector-adder' v1 v2))))
bitvector-adder {n} v1 v2 = strip-leading-zeroes-vec (bitvector-adder' v1 v2)
{-
pad-zeroes-length-lemma : (l1 l2 : BinaryNat) → length (pad-zeroes' l1 (length l2)) ≡ length (pad-zeroes' l2 (length l1))
-}
Memory : (n : Nat) → Set
Memory n = BitVector n