]> matita.cs.unibo.it Git - helm.git/blob - helm/software/helena/src/common/layer.ml
- we add the missing layer constraint on applicability condition
[helm.git] / helm / software / helena / src / common / layer.ml
1 (*
2     ||M||  This file is part of HELM, an Hypertextual, Electronic        
3     ||A||  Library of Mathematics, developed at the Computer Science     
4     ||T||  Department, University of Bologna, Italy.                     
5     ||I||                                                                
6     ||T||  HELM is free software; you can redistribute it and/or         
7     ||A||  modify it under the terms of the GNU General Public License   
8     \   /  version 2 or (at your option) any later version.              
9      \ /   This software is distributed as is, NO WARRANTY.              
10       V_______________________________________________________________ *)
11
12 module H = Hashtbl
13
14 module L = Log
15 module G = Options
16 module J = Marks
17
18 type value = Inf                 (* infinite layer *)
19            | Fin of int          (* finite layer *)
20            | Ref of J.mark * int (* referred layer, step *)
21            | Unk                 (* no layer set *)
22
23 type layer = {
24   mutable v: value; (* value *)  
25           s: bool;  (* static layer? *)
26   mutable b: bool;  (* beta allowed? *)
27 }
28
29 type status = (J.mark, layer) H.t (* environment for layer variables *)
30
31 (* Internal functions *******************************************************)
32
33 let level = 7
34
35 let env_size = 1300
36
37 let warn s = L.warn (pred level) s
38
39 let zero = Fin 0
40
41 let string_of_value k = function
42    | Inf        -> ""
43    | Fin i      -> string_of_int i
44    | Ref (k, i) -> "-" ^ J.string_of_mark k ^ "-" ^ string_of_int i
45    | Unk        -> "-" ^ J.string_of_mark k
46
47 let pp_table st =
48    let map k n =
49       warn (Printf.sprintf "%s: v %s (s:%b b:%b)" 
50          (J.string_of_mark k) (string_of_value k n.v) n.s n.b
51       )
52    in
53    H.iter map st 
54
55 let cell s v = {
56    v = v; s = s; b = false
57 }
58
59 let empty () = cell true Unk
60
61 let dynamic k i = cell false (Ref (k, i))
62
63 let find_with_default st default k =
64    try H.find st k with Not_found -> H.add st k default; default 
65
66 let find st k =
67    try H.find st k with Not_found -> assert false 
68
69 let rec resolve_key_with_default st default k = match find_with_default st default k with
70    | {v = Ref (k, i)} when i = 0 -> resolve_key_with_default st default k
71    | cell                        -> k, cell
72
73 let rec resolve_key st k = match find st k with
74    | {v = Ref (k, i)} when i = 0 -> resolve_key st k
75    | cell                        -> k, cell
76
77 let resolve_layer st = function
78    | {v = Ref (k, i)} when i = 0 -> resolve_key st k
79    | cell                        -> J.null_mark, cell
80
81 let rec generated st h i =
82    let default = dynamic h i in
83    let k = J.new_mark () in
84    match resolve_key_with_default st default k with
85       | k, n when n = default   -> if !G.trace >= level then pp_table st; n
86       | _, n when n.s = true -> generated st h i
87       | _                    -> assert false
88
89 let assert_finite st n j =
90    if !G.trace >= level then warn (Printf.sprintf "ASSERT FINITE %u" j);
91    let rec aux (k, n) j = match n.v with    
92       | Fin i when i = j -> true
93       | Fin i            ->
94          Printf.printf "binder %s is %u but must be %u\n" (J.string_of_mark k) i j; true (**)
95       | Inf              ->
96          Printf.printf "binder %s is infinite but must be %u\n" (J.string_of_mark k) j; true (**)
97       | Unk              -> n.v <- Fin j; if !G.trace >= level then pp_table st; true
98       | Ref (k, i)       -> n.v <- Fin j; aux (resolve_key st k) (i+j) 
99    in
100    let k, n = resolve_layer st n in
101 (*   if j = 0 && n.b then begin
102       Printf.printf "^Pi reduction on binder %s\n" (J.string_of_mark k); false (**)
103    end else *)
104       aux (k, n) j
105
106 let assert_infinite st n =
107    if !G.trace >= level then warn "ASSERT INFINITE";
108    let rec aux (k, n) = match n.v with
109       | Inf        -> true
110       | Fin i      -> 
111          Printf.printf "binder %s is %u but must be infinite\n" (J.string_of_mark k) i; true (**)
112       | Unk        -> n.v <- Inf; if !G.trace >= level then pp_table st; true
113       | Ref (k, _) -> n.v <- Inf; aux (resolve_key st k) 
114    in
115    aux (resolve_layer st n)
116
117 (* Interface functions ******************************************************)
118
119 let initial_status () =
120    H.create env_size
121
122 let refresh_status st = st 
123
124 let infinite = cell true Inf
125
126 let finite i = cell true (Fin i)
127
128 let one = finite 1
129
130 let two = finite 2
131
132 let rec unknown st =
133    if !G.trace >= level then warn "UNKNOWN";
134    let default = empty () in
135    let k = J.new_mark () in
136    match resolve_key_with_default st default k with
137       | k, n when n = default -> if !G.trace >= level then pp_table st; cell true (Ref (k, 0))
138       | _, n when n.s = true  -> n
139       | _                     -> unknown st
140
141 let minus st n j =
142    if !G.trace >= level then warn (Printf.sprintf "MINUS %u" j);
143    let rec aux k n j = match n.v with
144       | Inf              -> cell false n.v
145       | Fin i when i > j -> cell false (Fin (i - j))
146       | Fin _            -> cell false zero
147       | Unk              ->
148          if k = J.null_mark then assert false else generated st k j
149       | Ref (k, i)       -> 
150          let k, n = resolve_key st k in
151          aux k n (i+j)      
152    in
153    let k, n = resolve_layer st n in
154    aux k n j
155
156 let to_string st n =
157    let k, n = resolve_layer st n in
158    string_of_value k n.v
159
160 let assert_not_zero st n =
161    if !G.trace >= level then warn "ASSERT NOT ZERO";
162    let k, n = resolve_layer st n in
163    match n.b, n.v with
164       | true, _                -> n.b
165 (*      | _   , Fin i when i = 0 ->   
166          Printf.printf "^Pi reduction on binder %s\n" (J.string_of_mark k); false *) (**)
167 (*      if n.s && n.v = Fin 1 then Printf.printf "Pi reduction on binder %s\n" (J.string_of_mark k); *)      
168       | _                      -> n.b <- true; if !G.trace >= level then pp_table st; n.b
169
170 let assert_zero st n = assert_finite st n 0
171
172 let assert_equal st n1 n2 =
173    let k1, n1 = resolve_layer st n1 in
174    let k2, n2 = resolve_layer st n2 in
175    if n1 = n2 then true else
176    let b =
177       if not n1.b || assert_not_zero st n2 then match n1.v with
178          | Inf   -> assert_infinite st n2
179          | Fin i -> assert_finite st n2 i
180          | Unk   -> true
181          | Ref _ -> assert false
182       else false
183    in begin
184    if !G.trace >= level then warn "ASSERT EQUAL";
185    if b && k1 <> J.null_mark && k2 <> J.null_mark then begin
186       n1.v <- Ref (k2, 0); if !G.trace >= level then pp_table st
187    end; b end
188
189 let is_not_zero st n  =
190    let _, n = resolve_layer st n in n.v <> zero