]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_notation/cicNotationFwd.ml
snapshort
[helm.git] / helm / ocaml / cic_notation / cicNotationFwd.ml
1 (* Copyright (C) 2004-2005, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://helm.cs.unibo.it/
24  *)
25
26 open CicNotationEnv
27 open CicNotationPt
28
29 (* XXX ZACK: switched to CicNotationUtil.names_of_term, commented code below to
30  * be removes as soon as we believe implementation are equivalent *)
31 (* let meta_names_of term =
32   let rec names = ref [] in
33   let add_name n =
34     if List.mem n !names then ()
35     else names := n :: !names
36   in
37   let rec aux = function
38     | AttributedTerm (_, term) -> aux term
39     | Appl terms -> List.iter aux terms
40     | Binder (_, _, body) -> aux body
41     | Case (term, indty, outty_opt, patterns) ->
42         aux term ;
43         aux_opt outty_opt ;
44         List.iter aux_branch patterns
45     | LetIn (_, t1, t2) ->
46         aux t1 ;
47         aux t2
48     | LetRec (_, definitions, body) ->
49         List.iter aux_definition definitions ;
50         aux body
51     | Uri (_, Some substs) -> aux_substs substs
52     | Ident (_, Some substs) -> aux_substs substs
53     | Meta (_, substs) -> aux_meta_substs substs
54
55     | Implicit
56     | Ident _
57     | Num _
58     | Sort _
59     | Symbol _
60     | Uri _
61     | UserInput -> ()
62
63     | Magic magic -> aux_magic magic
64     | Variable var -> aux_variable var
65
66     | _ -> assert false
67   and aux_opt = function
68     | Some term -> aux term
69     | None -> ()
70   and aux_capture_var (_, ty_opt) = aux_opt ty_opt
71   and aux_branch (pattern, term) =
72     aux_pattern pattern ;
73     aux term
74   and aux_pattern (head, vars) = 
75     List.iter aux_capture_var vars
76   and aux_definition (var, term, i) =
77     aux_capture_var var ;
78     aux term
79   and aux_substs substs = List.iter (fun (_, term) -> aux term) substs
80   and aux_meta_substs meta_substs = List.iter aux_opt meta_substs
81   and aux_variable = function
82     | NumVar name -> add_name name
83     | IdentVar name -> add_name name
84     | TermVar name -> add_name name
85     | FreshVar _ -> ()
86     | Ascription _ -> assert false
87   and aux_magic = function
88     | Default (t1, t2)
89     | Fold (_, t1, _, t2) ->
90         aux t1 ;
91         aux t2
92     | _ -> assert false
93   in
94   aux term ;
95   !names *)
96
97 let unopt_names names env =
98   let rec aux acc = function
99     | (name, (ty, v)) :: tl when List.mem name names ->
100         (match ty, v with
101         | OptType ty, OptValue (Some v) -> aux ((name, (ty, v)) :: acc) tl
102         | _ -> assert false)
103     | _ :: tl -> aux acc tl
104       (* some pattern may contain only meta names, thus we trash all others *)
105     | [] -> acc
106   in
107   aux [] env
108
109 let head_names names env =
110   let rec aux acc = function
111     | (name, (ty, v)) :: tl when List.mem name names ->
112         (match ty, v with
113         | ListType ty, ListValue (v :: _) -> aux ((name, (ty, v)) :: acc) tl
114         | _ -> assert false)
115     | _ :: tl -> aux acc tl
116       (* base pattern may contain only meta names, thus we trash all others *)
117     | [] -> acc
118   in
119   aux [] env
120
121 let tail_names names env =
122   let rec aux acc = function
123     | (name, (ty, v)) :: tl when List.mem name names ->
124         (match ty, v with
125         | ListType ty, ListValue (_ :: vtl) ->
126             aux ((name, (ListType ty, ListValue vtl)) :: acc) tl
127         | _ -> assert false)
128     | binding :: tl -> aux (binding :: acc) tl
129     | [] -> acc
130   in
131   aux [] env
132
133 let instantiate_level2 env term =
134   let fresh_env = ref [] in
135   let lookup_fresh_name n =
136     try
137       List.assoc n !fresh_env
138     with Not_found ->
139       let new_name = CicNotationUtil.fresh_name () in
140       fresh_env := (n, new_name) :: !fresh_env;
141       new_name
142   in
143   let rec aux env term =
144     match term with
145     | AttributedTerm (_, term) -> aux env term
146     | Appl terms -> Appl (List.map (aux env) terms)
147     | Binder (binder, var, body) ->
148         Binder (binder, aux_capture_var env var, aux env body)
149     | Case (term, indty, outty_opt, patterns) ->
150         Case (aux env term, indty, aux_opt env outty_opt,
151           List.map (aux_branch env) patterns)
152     | LetIn (var, t1, t2) ->
153         LetIn (aux_capture_var env var, aux env t1, aux env t2)
154     | LetRec (kind, definitions, body) ->
155         LetRec (kind, List.map (aux_definition env) definitions, aux env body)
156     | Uri (name, None) -> Uri (name, None)
157     | Uri (name, Some substs) -> Uri (name, Some (aux_substs env substs))
158     | Ident (name, Some substs) -> Ident (name, Some (aux_substs env substs))
159     | Meta (index, substs) -> Meta (index, aux_meta_substs env substs)
160
161     | Implicit
162     | Ident _
163     | Num _
164     | Sort _
165     | Symbol _
166     | UserInput -> term
167
168     | Magic magic -> aux_magic env magic
169     | Variable var -> aux_variable env var
170
171     | _ -> assert false
172   and aux_opt env = function
173     | Some term -> Some (aux env term)
174     | None -> None
175   and aux_capture_var env (name, ty_opt) = (aux env name, aux_opt env ty_opt)
176   and aux_branch env (pattern, term) =
177     (aux_pattern env pattern, aux env term)
178   and aux_pattern env (head, vars) =
179     (head, List.map (aux_capture_var env) vars)
180   and aux_definition env (var, term, i) =
181     (aux_capture_var env var, aux env term, i)
182   and aux_substs env substs =
183     List.map (fun (name, term) -> (name, aux env term)) substs
184   and aux_meta_substs env meta_substs = List.map (aux_opt env) meta_substs
185   and aux_variable env = function
186     | NumVar name -> Num (lookup_num env name, 0)
187     | IdentVar name -> Ident (lookup_string env name, None)
188     | TermVar name -> lookup_term env name
189     | FreshVar name -> Ident (lookup_fresh_name name, None)
190     | Ascription (term, name) -> assert false
191   and aux_magic env = function
192     | Default (some_pattern, none_pattern) ->
193         (match CicNotationUtil.names_of_term some_pattern with
194         | [] -> assert false (* some pattern must contain at least 1 name *)
195         | (name :: _) as names ->
196             (match lookup_value env name with
197             | OptValue (Some _) ->
198                 (* assumption: if "name" above is bound to Some _, then all
199                  * names returned by "meta_names_of" are bound to Some _ as well
200                  *)
201                 aux (unopt_names names env) some_pattern
202             | OptValue None -> aux env none_pattern
203             | _ -> assert false))
204     | Fold (`Left, base_pattern, names, rec_pattern) ->
205         let acc_name = List.hd names in (* names can't be empty, cfr. parser *)
206         let meta_names =
207           List.filter ((<>) acc_name)
208             (CicNotationUtil.names_of_term rec_pattern)
209         in
210         (match meta_names with
211         | [] -> assert false (* as above *)
212         | (name :: _) as names ->
213             let rec instantiate_fold_left acc env' =
214               prerr_endline "instantiate_fold_left";
215               match lookup_value env' name with
216               | ListValue (_ :: _) ->
217                   instantiate_fold_left 
218                     (let acc_binding = acc_name, (TermType, TermValue acc) in
219                      aux (acc_binding :: head_names names env') rec_pattern)
220                     (tail_names names env')
221               | ListValue [] -> acc
222               | _ -> assert false
223             in
224             instantiate_fold_left (aux env base_pattern) env)
225     | Fold (`Right, base_pattern, names, rec_pattern) ->
226         let acc_name = List.hd names in (* names can't be empty, cfr. parser *)
227         let meta_names =
228           List.filter ((<>) acc_name)
229             (CicNotationUtil.names_of_term rec_pattern)
230         in
231         (match meta_names with
232         | [] -> assert false (* as above *)
233         | (name :: _) as names ->
234             let rec instantiate_fold_right env' =
235               prerr_endline "instantiate_fold_right";
236               match lookup_value env' name with
237               | ListValue (_ :: _) ->
238                   let acc = instantiate_fold_right (tail_names names env') in
239                   let acc_binding = acc_name, (TermType, TermValue acc) in
240                   aux (acc_binding :: head_names names env') rec_pattern
241               | ListValue [] -> aux env base_pattern
242               | _ -> assert false
243             in
244             instantiate_fold_right env)
245     | _ -> assert false
246   in
247   aux env term
248