source: Deliverables/D3.3/id-lookup-branch/common/Identifiers.ma @ 1105

Last change on this file since 1105 was 1105, checked in by campbell, 8 years ago

Show that RTLabs graphs are closed on branch (i.e., all labels in
instructions are in the graph). Rather time consuming and fiddly.

File size: 7.1 KB
Line 
1include "basics/types.ma".
2include "ASM/String.ma".
3include "ASM/Arithmetic.ma".
4include "common/Errors.ma".
5
6(* identifiers and their generators are tagged to differentiate them, and to
7   provide extra type checking. *)
8
9(* in common/PreIdentifiers.ma, via Errors.ma.
10inductive identifier (tag:String) : Type[0] ≝
11  an_identifier : Word → identifier tag.
12*)
13
14record universe (tag:String) : Type[0] ≝
15{
16  next_identifier : Word;
17  counter_overflow: bool
18}.
19
20definition new_universe : ∀tag:String. universe tag ≝
21  λtag. mk_universe tag (zero ?) false.
22
23(* Fresh identifier generation uses delayed overflow checking.  To make sure
24   that the identifiers really were fresh, use the check_universe_ok function
25   below afterwards. *)
26definition fresh : ∀tag:String. universe tag → identifier tag × (universe tag) ≝
27  λtag.
28  λuniv: universe tag.
29  let 〈gen, carries〉 ≝ add_with_carries ? (next_identifier ? univ) (zero ?) true in
30    if get_index_v … carries 0 ? then
31      〈an_identifier tag (next_identifier ? univ), mk_universe tag gen true〉
32    else
33      〈an_identifier tag (next_identifier ? univ), mk_universe tag gen false〉.
34  //
35qed.
36
37axiom TooManyIdentifiers : String.
38
39definition check_universe_ok : ∀tag:String. universe tag → res unit ≝
40  λtag, univ.
41  if counter_overflow ? univ
42  then Error ? (msg TooManyIdentifiers)
43  else OK ? it.
44
45definition eq_identifier : ∀t. identifier t → identifier t → bool ≝
46  λt,l,r.
47  match l with
48  [ an_identifier l' ⇒
49    match r with
50    [ an_identifier r' ⇒
51      eq_bv ? l' r'
52    ]
53  ].
54
55lemma eq_identifier_elim : ∀P:bool → Type[0]. ∀t,x,y.
56  (x = y → P true) → (x ≠ y → P false) →
57  P (eq_identifier t x y).
58#P #t * #x * #y #T #F
59change with (P (eq_bv ???))
60@eq_bv_elim [ /2/ | * #H @F % #E destruct /2/ ]
61qed.
62   
63definition word_of_identifier ≝
64  λt.
65  λl: identifier t.
66  match l with   
67  [ an_identifier l' ⇒ l'
68  ].
69
70definition identifier_eq : ∀tag:String. ∀x,y:identifier tag. (x=y) + (x≠y).
71#tag * #x * #y lapply (refl ? (eq_bv ? x y)) cases (eq_bv ? x y) in ⊢ (???% → %)
72#E [ % | %2 ]
73lapply E @eq_bv_elim
74[ #H #_ >H @refl | 2,3: #_ #H destruct | #H #_ % #H' destruct /2/ ]
75qed.
76
77definition identifier_of_nat : ∀tag:String. nat → identifier tag ≝
78  λtag,n. an_identifier tag (bitvector_of_nat ? n).
79
80
81(* Maps from identifiers to arbitrary types. *)
82
83include "ASM/BitVectorTrie.ma".
84
85inductive identifier_map (tag:String) (A:Type[0]) : Type[0] ≝
86  an_id_map : BitVectorTrie A 16 → identifier_map tag A.
87 
88definition empty_map : ∀tag:String. ∀A. identifier_map tag A ≝
89  λtag,A. an_id_map tag A (Stub A 16).
90
91definition lookup : ∀tag,A. identifier_map tag A → identifier tag → option A ≝
92  λtag,A,m,l. lookup_opt A 16 (match l with [ an_identifier l' ⇒ l' ])
93                              (match m with [ an_id_map m' ⇒ m' ]).
94
95(* Always adds the identifier to the map. *)
96definition add : ∀tag,A. identifier_map tag A → identifier tag → A → identifier_map tag A ≝
97λtag,A,m,l,a. an_id_map tag A (insert A 16 (match l with [ an_identifier l' ⇒ l' ]) a
98                                           (match m with [ an_id_map m' ⇒ m' ])).
99
100lemma lookup_add_hit : ∀tag,A,m,i,a.
101  lookup tag A (add tag A m i a) i = Some ? a.
102#tag #A * #m * #i #a
103@lookup_opt_insert_hit
104qed.
105
106lemma lookup_add_miss : ∀tag,A,m,i,j,a.
107  (notb (eq_identifier tag i j)) →
108  lookup tag A (add tag A m j a) i = lookup tag A m i.
109#tag #A * #m * #i * #j #a
110change with (notb (eq_bv ???) → ?)
111@lookup_opt_insert_miss
112qed.
113
114lemma lookup_add_oblivious : ∀tag,A,m,i,j,a.
115  (lookup tag A m i ≠ None ?) →
116  lookup tag A (add tag A m j a) i ≠ None ?.
117#tag #A #m #i #j #a #H
118lapply (lookup_add_miss … m i j a)
119@eq_identifier_elim
120[ #E #_ >E >lookup_add_hit % #N destruct
121| #_ #H' >H' //
122] qed.
123
124lemma lookup_add_cases : ∀tag,A,m,i,j,a,v.
125  lookup tag A (add tag A m i a) j = Some ? v →
126  (i=j ∧ v = a) ∨ lookup tag A m j = Some ? v.
127#tag #A #m #i #j #a #v
128cases (identifier_eq ? i j)
129[ #E >E >lookup_add_hit #H %1 destruct % //
130| #NE >lookup_add_miss /2/ @eq_identifier_elim /2/
131] qed.
132
133(* Extract every identifier, value pair from the map. *)
134definition elements : ∀tag,A. identifier_map tag A → list (identifier tag × A) ≝
135λtag,A,m.
136  fold ??? (λl,a,el. 〈an_identifier tag l, a〉::el)
137           (match m with [ an_id_map m' ⇒ m' ]) [ ].
138
139axiom MissingId : String.
140
141(* Only updates an existing entry; fails with an error otherwise. *)
142definition update : ∀tag,A. identifier_map tag A → identifier tag → A → res (identifier_map tag A) ≝
143λtag,A,m,l,a.
144  match update A 16 (match l with [ an_identifier l' ⇒ l' ]) a
145                    (match m with [ an_id_map m' ⇒ m' ]) with
146  [ None ⇒ Error ? ([MSG MissingId; CTX tag l]) (* missing identifier *)
147  | Some m' ⇒ OK ? (an_id_map tag A m')
148  ].
149
150definition foldi:
151  ∀A, B: Type[0].
152  ∀tag: String.
153  (identifier tag -> A -> B -> B) -> identifier_map tag A -> B -> B ≝
154λA,B,tag,f,m,b.
155  match m with
156  [ an_id_map m' ⇒ fold A B ? (λbv. f (an_identifier ? bv)) m' b ].
157
158(* A predicate that an identifier is in a map, and a failure-avoiding lookup
159   using it. *)
160
161definition present : ∀tag,A. identifier_map tag A → identifier tag → Prop ≝
162λtag,A,m,i. lookup … m i ≠ None ?.
163
164definition lookup_present : ∀tag,A. ∀m:identifier_map tag A. ∀id. present ?? m id → A ≝
165λtag,A,m,id. match lookup ?? m id return λx. x ≠ None ? → ? with [ Some a ⇒ λ_. a | None ⇒ λH.⊥ ].
166cases H #H'  cases (H' (refl ??)) qed.
167
168
169(* Sets *)
170
171inductive identifier_set (tag:String) : Type[0] ≝
172  an_id_set : BitVectorTrie unit 16 → identifier_set tag.
173
174definition empty_set : ∀tag:String. identifier_set tag ≝
175λtag. an_id_set tag (Stub unit 16).
176
177let rec add_set (tag:String) (s:identifier_set tag) (i:identifier tag) on s : identifier_set tag ≝
178  an_id_set tag (insert unit 16 (match i with [ an_identifier i' ⇒ i' ])
179                             it (match s with [ an_id_set s' ⇒ s' ])).
180
181definition singleton_set : ∀tag:String. identifier tag → identifier_set tag ≝
182λtag,i. add_set tag (empty_set tag) i.
183
184let rec mem_set (tag:String) (s:identifier_set tag) (i:identifier tag) on s : bool ≝
185  match lookup_opt ? 16 (match i with [ an_identifier i' ⇒ i' ])
186                        (match s with [ an_id_set s' ⇒ s' ]) with
187  [ None ⇒ false
188  | Some _ ⇒ true
189  ].
190
191let rec union_set (tag:String) (s:identifier_set tag) (s':identifier_set tag) on s : identifier_set tag ≝
192  an_id_set tag (merge unit 16 (match s with [ an_id_set s0 ⇒ s0 ])
193                               (match s' with [ an_id_set s1 ⇒ s1 ])).
194
195interpretation "identifier set union" 'union a b = (union_set ? a b).
196notation "∅" non associative with precedence 90 for @{ 'empty }.
197interpretation "empty identifier set" 'empty = (empty_set ?).
198interpretation "singleton identifier set" 'singl a = (add_set ? (empty_set ?) a).
199interpretation "identifier set membership" 'mem a b = (mem_set ? b a).
200
201lemma union_empty_l : ∀tag.∀s:identifier_set tag. ∅ ∪ s = s.
202#tag * //
203qed.
204
205lemma union_empty_r : ∀tag.∀s:identifier_set tag. s ∪ ∅ = s.
206#tag * #s cases (BitVectorTrie_Sn … s)
207[ * #x * #y #E >E //
208| #E >E //
209] qed.
Note: See TracBrowser for help on using the repository browser.