File size: 13,848 Bytes
7e1c831 | 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 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | (* Netlists of ternary threshold units, flat and in blocks, and the valuations they compute. *)
From Stdlib Require Import List Bool Arith ZArith Lia.
Import ListNotations.
From TH Require Import TwoHead.
(* ---- flat netlists ------------------------------------------------------------- *)
(* a unit: its bias and its predecessors, each a signal index with a weight *)
Record tu := TU { tb : Z; tin : list (nat * Z) }.
Fixpoint wsum (ins : list (nat * Z)) (E : nat -> bool) : Z :=
match ins with [] => 0%Z | (i, w) :: t => (w * b2z (E i) + wsum t E)%Z end.
Definition fire (u : tu) (E : nat -> bool) : bool := Z.leb 0 (tb u + wsum (tin u) E).
Definition setv (E : nat -> bool) (m : nat) (b : bool) : nat -> bool :=
fun i => if Nat.eqb i m then b else E i.
(* the units evaluated in order, the first at signal m *)
Fixpoint run (us : list tu) (m : nat) (E : nat -> bool) : nat -> bool :=
match us with [] => E | u :: t => run t (S m) (setv E m (fire u E)) end.
(* one step of a clocked netlist on n state bits: next value i is signal nx_i *)
Definition netstep (n : nat) (us : list tu) (nx : list nat) (x : list bool) : list bool :=
let F := run us n (fun i => nth i x false) in map F nx.
Lemma run_prefix : forall us m E i, i < m -> run us m E i = E i.
Proof.
induction us as [|u t IH]; intros m E i H; cbn [run]; [reflexivity|].
rewrite IH by lia. unfold setv. destruct (Nat.eqb_spec i m); [lia|reflexivity].
Qed.
Lemma wsum_ext : forall ins E E', (forall i w, In (i, w) ins -> E i = E' i) -> wsum ins E = wsum ins E'.
Proof.
induction ins as [|[i w] t IH]; intros E E' H; cbn [wsum]; [reflexivity|].
rewrite (H i w (or_introl eq_refl)), (IH E E'); [reflexivity|].
intros i' w' Hin. apply (H i' w'). right. exact Hin.
Qed.
Lemma fire_ext : forall u E E', (forall i w, In (i, w) (tin u) -> E i = E' i) -> fire u E = fire u E'.
Proof. intros u E E' H. unfold fire. rewrite (wsum_ext _ E E' H). reflexivity. Qed.
Definition reads_below (u : tu) (m : nat) : Prop := forall i w, In (i, w) (tin u) -> i < m.
Definition tu0 : tu := TU 0 [].
Lemma run_at : forall us m E j, j < length us ->
(forall k, k < length us -> reads_below (nth k us tu0) (m + k)) ->
run us m E (m + j) = fire (nth j us tu0) (run us m E).
Proof.
induction us as [|u t IH]; intros m E j Hj Hwf; cbn [length] in Hj, Hwf; [lia|].
destruct j as [|j].
- cbn [nth run]. rewrite Nat.add_0_r, run_prefix by lia. unfold setv at 1. rewrite Nat.eqb_refl.
apply fire_ext. intros i w Hin. rewrite run_prefix by (specialize (Hwf 0 ltac:(lia) i w Hin); lia).
unfold setv. destruct (Nat.eqb_spec i m); [specialize (Hwf 0 ltac:(lia) i w Hin); lia|reflexivity].
- cbn [nth run]. replace (m + S j) with (S m + j) by lia. apply IH; [lia|].
intros k Hk i w Hin. specialize (Hwf (S k) ltac:(lia) i w Hin). lia.
Qed.
(* ---- netlists in blocks ---------------------------------------------------------- *)
(* a signal is a state bit, or unit r of member j of block b *)
Inductive sref := SIn (i : nat) | SRef (b j r : nat).
Record su := SU { sb : Z; sin : list (sref * Z) }.
(* a block: count members of size units each; shape j lists the units of member j *)
Record block := Blk { bcount : nat; bsize : nat; bshape : nat -> list su }.
Definition blk0 : block := Blk 0 0 (fun _ => []).
Definition su0 : su := SU 0 [].
Fixpoint boff (bs : list block) (b : nat) : nat :=
match bs, b with
| _, O => 0
| [], S _ => 0
| blk :: t, S b' => bcount blk * bsize blk + boff t b'
end.
Definition idx (n : nat) (bs : list block) (x : sref) : nat :=
match x with
| SIn i => i
| SRef b j r => n + boff bs b + bsize (nth b bs blk0) * j + r
end.
Definition flat_unit (n : nat) (bs : list block) (u : su) : tu :=
TU (sb u) (map (fun p => (idx n bs (fst p), snd p)) (sin u)).
Definition flat_block (n : nat) (bs : list block) (blk : block) : list tu :=
concat (map (fun j => map (flat_unit n bs) (bshape blk j)) (seq 0 (bcount blk))).
Definition compile (n : nat) (bs : list block) : list tu := concat (map (flat_block n bs) bs).
Definition shaped (blk : block) : Prop := forall j, j < bcount blk -> length (bshape blk j) = bsize blk.
Definition sunit (bs : list block) (b j r : nat) : su := nth r (bshape (nth b bs blk0) j) su0.
Definition valid (bs : list block) (n : nat) (x : sref) : Prop :=
match x with
| SIn i => i < n
| SRef b j r => b < length bs /\ j < bcount (nth b bs blk0) /\ r < bsize (nth b bs blk0)
end.
(* each unit reads state bits, units of earlier blocks, or earlier units of its own member *)
Definition reads_back (bs : list block) (n b j r : nat) (x : sref) : Prop :=
match x with
| SIn i => i < n
| SRef b' j' r' => (b' < b /\ j' < bcount (nth b' bs blk0) /\ r' < bsize (nth b' bs blk0))
\/ (b' = b /\ j' = j /\ r' < r)
end.
Definition wf (bs : list block) (n : nat) : Prop :=
Forall shaped bs
/\ forall b j r x w, b < length bs -> j < bcount (nth b bs blk0) -> r < bsize (nth b bs blk0) ->
In (x, w) (sin (sunit bs b j r)) -> reads_back bs n b j r x.
Lemma length_concat_const : forall (A : Type) (ls : list (list A)) sz,
Forall (fun l => length l = sz) ls -> length (concat ls) = length ls * sz.
Proof.
intros A ls sz H. induction H as [|l ls Hl H IH]; [reflexivity|].
cbn [concat length]. rewrite length_app, IH, Hl. lia.
Qed.
Lemma length_flat_block : forall n bs blk, shaped blk ->
length (flat_block n bs blk) = bcount blk * bsize blk.
Proof.
intros n bs blk Hs. unfold flat_block.
rewrite length_concat_const with (sz := bsize blk).
- rewrite length_map, length_seq. reflexivity.
- apply Forall_forall. intros l Hl. apply in_map_iff in Hl as (j & <- & Hj).
apply in_seq in Hj. rewrite length_map. apply Hs. lia.
Qed.
Lemma nth_concat_const : forall (A : Type) (d : A) (ls : list (list A)) sz j r,
Forall (fun l => length l = sz) ls -> j < length ls -> r < sz ->
nth (sz * j + r) (concat ls) d = nth r (nth j ls []) d.
Proof.
intros A d ls sz j r Hall. revert j. induction Hall as [|l ls Hl Hall IH]; intros j Hj Hr;
cbn [length] in Hj; [lia|].
cbn [concat]. destruct j as [|j].
- rewrite Nat.mul_0_r, Nat.add_0_l, app_nth1 by lia. reflexivity.
- rewrite app_nth2 by nia. rewrite Hl. replace (sz * S j + r - sz) with (sz * j + r) by nia.
apply IH; [lia | exact Hr].
Qed.
Lemma nth_map_seq : forall (A : Type) (f : nat -> A) c j d, j < c -> nth j (map f (seq 0 c)) d = f j.
Proof.
intros A f c j d Hj. rewrite (nth_indep _ d (f 0)) by (rewrite length_map, length_seq; exact Hj).
rewrite map_nth, seq_nth by exact Hj. reflexivity.
Qed.
Lemma nth_map_d : forall (A B : Type) (g : A -> B) l r d d', r < length l -> nth r (map g l) d = g (nth r l d').
Proof.
intros A B g l r d d' Hr. rewrite (nth_indep _ d (g d')) by (rewrite length_map; exact Hr).
apply map_nth.
Qed.
Lemma flat_block_nth : forall n bs blk j r, shaped blk -> j < bcount blk -> r < bsize blk ->
nth (bsize blk * j + r) (flat_block n bs blk) tu0 = flat_unit n bs (nth r (bshape blk j) su0).
Proof.
intros n bs blk j r Hs Hj Hr. unfold flat_block.
rewrite nth_concat_const with (sz := bsize blk); [| | rewrite length_map, length_seq; exact Hj | exact Hr].
- rewrite (nth_map_seq _ (fun j => map (flat_unit n bs) (bshape blk j)) (bcount blk) j [] Hj).
apply nth_map_d. rewrite Hs by exact Hj. exact Hr.
- apply Forall_forall. intros l Hl. apply in_map_iff in Hl as (j' & <- & Hj').
apply in_seq in Hj'. rewrite length_map. apply Hs. lia.
Qed.
Lemma compile_nth : forall n bs b j r, Forall shaped bs -> b < length bs ->
j < bcount (nth b bs blk0) -> r < bsize (nth b bs blk0) ->
nth (boff bs b + bsize (nth b bs blk0) * j + r) (compile n bs) tu0
= flat_unit n bs (sunit bs b j r).
Proof.
intros n bs. unfold compile, sunit.
assert (G : forall pre, Forall shaped pre ->
forall b j r, b < length pre -> j < bcount (nth b pre blk0) -> r < bsize (nth b pre blk0) ->
nth (boff pre b + bsize (nth b pre blk0) * j + r) (concat (map (flat_block n bs) pre)) tu0
= flat_unit n bs (nth r (bshape (nth b pre blk0) j) su0)).
{ induction pre as [|blk t IH]; intros Hsh b j r Hb Hj Hr; cbn [length] in Hb; [lia|].
inversion Hsh as [|? ? Hs1 Hst]; subst.
cbn [map concat]. destruct b as [|b].
- cbn [boff nth] in *. rewrite Nat.add_0_l, app_nth1.
+ apply flat_block_nth; assumption.
+ rewrite length_flat_block by exact Hs1. nia.
- cbn [boff nth] in *. rewrite app_nth2 by (rewrite length_flat_block by exact Hs1; lia).
rewrite length_flat_block by exact Hs1.
replace (bcount blk * bsize blk + boff t b + bsize (nth b t blk0) * j + r - bcount blk * bsize blk)
with (boff t b + bsize (nth b t blk0) * j + r) by lia.
apply IH; [exact Hst | lia | exact Hj | exact Hr]. }
intros b j r Hsh Hb Hj Hr. apply G; assumption.
Qed.
Lemma length_compile_gen : forall n bs0 bs, Forall shaped bs ->
length (concat (map (flat_block n bs0) bs)) = boff bs (length bs).
Proof.
intros n bs0 bs H. induction H as [|blk t Hs Ht IH]; [reflexivity|].
cbn [map concat length boff]. rewrite length_app, length_flat_block by exact Hs. rewrite IH. reflexivity.
Qed.
Lemma length_compile : forall n bs, Forall shaped bs -> length (compile n bs) = boff bs (length bs).
Proof. intros n bs H. apply length_compile_gen. exact H. Qed.
Lemma boff_mono : forall bs b b', b' < b -> b <= length bs ->
boff bs b' + bcount (nth b' bs blk0) * bsize (nth b' bs blk0) <= boff bs b.
Proof.
induction bs as [|blk t IH]; intros b b' Hb Hl; cbn [length] in Hl; [lia|].
destruct b as [|b]; [lia|]. destruct b' as [|b'].
- cbn [boff nth]. lia.
- cbn [boff nth]. specialize (IH b b' ltac:(lia) ltac:(lia)). lia.
Qed.
Lemma idx_lt : forall bs n b j r, b < length bs -> j < bcount (nth b bs blk0) -> r < bsize (nth b bs blk0) ->
idx n bs (SRef b j r) < n + boff bs (S b).
Proof.
intros bs n b j r Hb Hj Hr. cbn [idx].
pose proof (boff_mono bs (S b) b ltac:(lia) ltac:(lia)). nia.
Qed.
Lemma idx_lt_total : forall bs n x, valid bs n x -> idx n bs x < n + boff bs (length bs).
Proof.
intros bs n [i|b j r] Hv; cbn [valid] in Hv; [cbn [idx]; lia|].
destruct Hv as (Hb & Hj & Hr). pose proof (idx_lt bs n b j r Hb Hj Hr).
destruct (Nat.eq_dec (S b) (length bs)) as [E|E]; [rewrite <- E; exact H|].
pose proof (boff_mono bs (length bs) (S b) ltac:(lia) ltac:(lia)). lia.
Qed.
(* the structured unit fired on a valuation of its signals *)
Fixpoint swsum (ins : list (sref * Z)) (V : sref -> bool) : Z :=
match ins with [] => 0%Z | (x, w) :: t => (w * b2z (V x) + swsum t V)%Z end.
Definition sfire' (u : su) (V : sref -> bool) : bool := Z.leb 0 (sb u + swsum (sin u) V).
Lemma wsum_flat : forall n bs ins E,
wsum (map (fun p => (idx n bs (fst p), snd p)) ins) E = swsum ins (fun x => E (idx n bs x)).
Proof. intros n bs ins E. induction ins as [|[x w] t IH]; cbn [map wsum swsum fst snd]; [reflexivity|]. rewrite IH. reflexivity. Qed.
Lemma swsum_ext : forall ins V V', (forall x w, In (x, w) ins -> V x = V' x) -> swsum ins V = swsum ins V'.
Proof.
induction ins as [|[x w] t IH]; intros V V' H; cbn [swsum]; [reflexivity|].
rewrite (H x w (or_introl eq_refl)), (IH V V'); [reflexivity|].
intros x' w' Hin. apply (H x' w'). right. exact Hin.
Qed.
Lemma wf_reads_below : forall bs n, wf bs n ->
forall k, k < length (compile n bs) -> reads_below (nth k (compile n bs) tu0) (n + k).
Proof.
intros bs n [Hsh Hrd] k Hk. rewrite length_compile in Hk by exact Hsh.
assert (Hloc : exists b j r, b < length bs /\ j < bcount (nth b bs blk0) /\ r < bsize (nth b bs blk0)
/\ k = boff bs b + bsize (nth b bs blk0) * j + r).
{ clear -Hk Hsh. revert k Hk. induction Hsh as [|blk t Hs Ht IH]; intros k Hk; cbn [boff length] in Hk; [lia|].
destruct (Nat.lt_ge_cases k (bcount blk * bsize blk)) as [Hl|Hg].
- exists 0, (k / bsize blk), (k mod bsize blk).
assert (bsize blk <> 0) by (intro E; rewrite E in Hl; lia).
cbn [nth length boff]. split; [lia|]. split; [apply Nat.Div0.div_lt_upper_bound; nia|].
split; [apply Nat.mod_upper_bound; exact H|]. rewrite (Nat.div_mod k (bsize blk)) at 1 by exact H. lia.
- destruct (IH (k - bcount blk * bsize blk) ltac:(lia)) as (b & j & r & Hb & Hj & Hr & Hk').
exists (S b), j, r. cbn [nth length boff]. split; [lia|]. split; [exact Hj|]. split; [exact Hr|]. lia. }
destruct Hloc as (b & j & r & Hb & Hj & Hr & ->).
rewrite compile_nth by assumption.
intros i w Hin. unfold flat_unit in Hin. cbn [tin] in Hin.
apply in_map_iff in Hin as ([x w'] & Heq & Hin). cbn [fst snd] in Heq. injection Heq as <- <-.
specialize (Hrd b j r x w' Hb Hj Hr Hin).
destruct x as [i|b' j' r']; cbn [reads_back idx] in *; [lia|].
destruct Hrd as [(Hb' & Hj' & Hr')|(-> & -> & Hr')]; [|lia].
pose proof (boff_mono bs b b' Hb' ltac:(lia)). nia.
Qed.
(* the value of a state bit, and of a unit from the values of its predecessors *)
Lemma net_in : forall bs n X i, i < n -> run (compile n bs) n X (idx n bs (SIn i)) = X i.
Proof. intros bs n X i H. cbn [idx]. apply run_prefix. exact H. Qed.
Lemma net_unit : forall bs n X b j r, wf bs n ->
b < length bs -> j < bcount (nth b bs blk0) -> r < bsize (nth b bs blk0) ->
run (compile n bs) n X (idx n bs (SRef b j r))
= sfire' (sunit bs b j r) (fun x => run (compile n bs) n X (idx n bs x)).
Proof.
intros bs n X b j r Hwf Hb Hj Hr. cbn [idx].
replace (n + boff bs b + bsize (nth b bs blk0) * j + r) with (n + (boff bs b + bsize (nth b bs blk0) * j + r)) by lia.
rewrite run_at.
- rewrite compile_nth by (destruct Hwf; assumption). unfold fire, flat_unit, sfire'. cbn [tb tin].
rewrite wsum_flat. reflexivity.
- rewrite length_compile by (destruct Hwf; assumption).
pose proof (idx_lt_total bs n (SRef b j r) (conj Hb (conj Hj Hr))) as H. cbn [idx] in H. lia.
- apply wf_reads_below. exact Hwf.
Qed.
|