1 | |
---|
2 | include "basics/types.ma". |
---|
3 | include "ASM/String.ma". |
---|
4 | include "ASM/Arithmetic.ma". |
---|
5 | include "common/Errors.ma". |
---|
6 | |
---|
7 | (* identifiers and their generators are tagged to differentiate them, and to |
---|
8 | provide extra type checking. *) |
---|
9 | |
---|
10 | (* in common/PreIdentifiers.ma, via Errors.ma. |
---|
11 | inductive identifier (tag:String) : Type[0] ≝ |
---|
12 | an_identifier : Word → identifier tag. |
---|
13 | *) |
---|
14 | |
---|
15 | record universe (tag:String) : Type[0] ≝ |
---|
16 | { next_identifier : Word }. |
---|
17 | |
---|
18 | |
---|
19 | definition new_universe : ∀tag:String. universe tag ≝ |
---|
20 | λtag. mk_universe tag (zero ?). |
---|
21 | |
---|
22 | axiom OutOfIdentifiers : String. |
---|
23 | |
---|
24 | definition fresh : ∀tag. universe tag → res (identifier tag × (universe tag)) ≝ |
---|
25 | λtag,g. |
---|
26 | let 〈gen, carries〉 ≝ add_with_carries ? (next_identifier ? g) (zero ?) true in |
---|
27 | if get_index_v ?? carries 0 ? then Error ? (msg OutOfIdentifiers) else |
---|
28 | OK ? 〈an_identifier tag (next_identifier ? g), mk_universe tag gen〉. |
---|
29 | // qed. |
---|
30 | |
---|
31 | definition eq_identifier ≝ |
---|
32 | λt. |
---|
33 | λl, r: identifier t. |
---|
34 | match l with |
---|
35 | [ an_identifier l' ⇒ |
---|
36 | match r with |
---|
37 | [ an_identifier r' ⇒ |
---|
38 | eq_bv ? l' r' |
---|
39 | ] |
---|
40 | ]. |
---|
41 | |
---|
42 | |
---|
43 | definition word_of_identifier ≝ |
---|
44 | λt. |
---|
45 | λl: identifier t. |
---|
46 | match l with |
---|
47 | [ an_identifier l' ⇒ l' |
---|
48 | ]. |
---|
49 | |
---|
50 | definition identifier_eq : ∀tag:String. ∀x,y:identifier tag. (x=y) + (x≠y). |
---|
51 | #tag * #x * #y lapply (refl ? (eq_bv ? x y)) cases (eq_bv ? x y) in ⊢ (???% → %) |
---|
52 | #E [ % | %2 ] |
---|
53 | lapply E @eq_bv_elim |
---|
54 | [ #H #_ >H @refl | 2,3: #_ #H destruct | #H #_ % #H' destruct /2/ ] |
---|
55 | qed. |
---|
56 | |
---|
57 | definition identifier_of_nat : ∀tag:String. nat → identifier tag ≝ |
---|
58 | λtag,n. an_identifier tag (bitvector_of_nat ? n). |
---|
59 | |
---|
60 | |
---|
61 | (* Maps from identifiers to arbitrary types. *) |
---|
62 | |
---|
63 | include "ASM/BitVectorTrie.ma". |
---|
64 | |
---|
65 | inductive identifier_map (tag:String) (A:Type[0]) : Type[0] ≝ |
---|
66 | an_id_map : BitVectorTrie A 16 → identifier_map tag A. |
---|
67 | |
---|
68 | definition empty_map : ∀tag:String. ∀A. identifier_map tag A ≝ |
---|
69 | λtag,A. an_id_map tag A (Stub A 16). |
---|
70 | |
---|
71 | definition lookup : ∀tag,A. identifier_map tag A → identifier tag → option A ≝ |
---|
72 | λtag,A,m,l. lookup_opt A 16 (match l with [ an_identifier l' ⇒ l' ]) |
---|
73 | (match m with [ an_id_map m' ⇒ m' ]). |
---|
74 | |
---|
75 | (* Always adds the identifier to the map. *) |
---|
76 | definition add : ∀tag,A. identifier_map tag A → identifier tag → A → identifier_map tag A ≝ |
---|
77 | λtag,A,m,l,a. an_id_map tag A (insert A 16 (match l with [ an_identifier l' ⇒ l' ]) a |
---|
78 | (match m with [ an_id_map m' ⇒ m' ])). |
---|
79 | |
---|
80 | axiom MissingId : String. |
---|
81 | |
---|
82 | (* Only updates an existing entry; fails with an error otherwise. *) |
---|
83 | definition update : ∀tag,A. identifier_map tag A → identifier tag → A → res (identifier_map tag A) ≝ |
---|
84 | λtag,A,m,l,a. |
---|
85 | match update A 16 (match l with [ an_identifier l' ⇒ l' ]) a |
---|
86 | (match m with [ an_id_map m' ⇒ m' ]) with |
---|
87 | [ None ⇒ Error ? ([MSG MissingId; CTX tag l]) (* missing identifier *) |
---|
88 | | Some m' ⇒ OK ? (an_id_map tag A m') |
---|
89 | ]. |
---|
90 | |
---|
91 | (* Sets *) |
---|
92 | |
---|
93 | inductive identifier_set (tag:String) : Type[0] ≝ |
---|
94 | an_id_set : BitVectorTrie unit 16 → identifier_set tag. |
---|
95 | |
---|
96 | definition empty_set : ∀tag:String. identifier_set tag ≝ |
---|
97 | λtag. an_id_set tag (Stub unit 16). |
---|
98 | |
---|
99 | definition add_set : ∀tag:String. identifier_set tag → identifier tag → identifier_set tag ≝ |
---|
100 | λtag,s,i. an_id_set tag (insert unit 16 (match i with [ an_identifier i' ⇒ i' ]) |
---|
101 | it (match s with [ an_id_set s' ⇒ s' ])). |
---|
102 | |
---|
103 | definition singleton_set : ∀tag:String. identifier tag → identifier_set tag ≝ |
---|
104 | λtag,i. add_set tag (empty_set tag) i. |
---|
105 | |
---|
106 | definition mem_set : ∀tag:String. identifier_set tag → identifier tag → bool ≝ |
---|
107 | λtag,s,i. match lookup_opt ? 16 (match i with [ an_identifier i' ⇒ i' ]) |
---|
108 | (match s with [ an_id_set s' ⇒ s' ]) with |
---|
109 | [ None ⇒ false |
---|
110 | | Some _ ⇒ true |
---|
111 | ]. |
---|
112 | |
---|
113 | definition union_set : ∀tag:String. identifier_set tag → identifier_set tag → identifier_set tag ≝ |
---|
114 | λtag,s,s'. an_id_set tag (merge unit 16 (match s with [ an_id_set s0 ⇒ s0 ]) |
---|
115 | (match s' with [ an_id_set s1 ⇒ s1 ])). |
---|
116 | |
---|
117 | interpretation "identifier set union" 'union a b = (union_set ? a b). |
---|
118 | notation "∅" non associative with precedence 90 for @{ 'empty }. |
---|
119 | interpretation "empty identifier set" 'empty = (empty_set ?). |
---|
120 | interpretation "singleton identifier set" 'singl a = (add_set ? (empty_set ?) a). |
---|