]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_textual_parser/cicTextualParser.mly
Aliases definition removed from the
[helm.git] / helm / ocaml / cic_textual_parser / cicTextualParser.mly
1 /* Copyright (C) 2000, 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://cs.unibo.it/helm/.
24  */
25
26 %{
27  open Cic;;
28  module U = UriManager;;
29
30  exception InvalidSuffix of string;;
31  exception InductiveTypeURIExpected;;
32  exception UnknownIdentifier of string;;
33  exception ExplicitNamedSubstitutionAppliedToRel;;
34  exception TheLeftHandSideOfAnExplicitNamedSubstitutionMustBeAVariable;;
35  
36  (* merge removing duplicates of two lists free of duplicates *)
37  let union dom1 dom2 =
38   let rec filter =
39    function
40       [] -> []
41     | he::tl ->
42        if List.mem he dom1 then filter tl else he::(filter tl)
43   in
44    dom1 @ (filter dom2)
45  ;;
46
47  let get_index_in_list e =
48   let rec aux i =
49    function
50       [] -> raise Not_found
51     | (Some he)::_ when he = e -> i
52     | _::tl -> aux (i+1) tl
53   in
54    aux 1
55  ;;
56
57  (* Returns the first meta whose number is above the *)
58  (* number of the higher meta.                       *)
59  (*CSC: cut&pasted from proofEngine.ml *)
60  let new_meta () =
61   let rec aux =
62    function
63       None,[] -> 1
64     | Some n,[] -> n
65     | None,(n,_,_)::tl -> aux (Some n,tl)
66     | Some m,(n,_,_)::tl -> if n > m then aux (Some n,tl) else aux (Some m,tl)
67   in
68    1 + aux (None,!CicTextualParser0.metasenv)
69  ;;
70
71  (* identity_relocation_list_for_metavariable i canonical_context         *)
72  (* returns the identity relocation list, which is the list [1 ; ... ; n] *)
73  (* where n = List.length [canonical_context]                             *)
74  (*CSC: ma mi basta la lunghezza del contesto canonico!!!*)
75  (*CSC: cut&pasted from proofEngine.ml *)
76  let identity_relocation_list_for_metavariable canonical_context =
77   let canonical_context_length = List.length canonical_context in
78    let rec aux =
79     function
80        (_,[]) -> []
81      | (n,None::tl) -> None::(aux ((n+1),tl))
82      | (n,_::tl) -> (Some (Cic.Rel n))::(aux ((n+1),tl))
83    in
84     aux (1,canonical_context)
85  ;;
86
87  let deoptionize_exp_named_subst =
88   function
89      None -> [], (function _ -> [])
90    | Some (dom,mk_exp_named_subst) -> dom,mk_exp_named_subst
91  ;;
92
93  let term_of_con_uri uri exp_named_subst =
94   Const (uri,exp_named_subst)
95  ;;
96
97  let term_of_var_uri uri exp_named_subst =
98   Var (uri,exp_named_subst)
99  ;;
100
101  let term_of_indty_uri (uri,tyno) exp_named_subst =
102   MutInd (uri, tyno, exp_named_subst)
103  ;;
104
105  let term_of_indcon_uri (uri,tyno,consno) exp_named_subst =
106   MutConstruct (uri, tyno, consno, exp_named_subst)
107  ;;
108
109  let term_of_uri uri =
110   match uri with
111      CicTextualParser0.ConUri uri ->
112       term_of_con_uri uri
113    | CicTextualParser0.VarUri uri ->
114       term_of_var_uri uri
115    | CicTextualParser0.IndTyUri (uri,tyno) ->
116       term_of_indty_uri (uri,tyno) 
117    | CicTextualParser0.IndConUri (uri,tyno,consno) ->
118       term_of_indcon_uri (uri,tyno,consno)
119  ;;
120
121  let var_uri_of_id id interp =
122   match interp id with
123      None -> raise (UnknownIdentifier id)
124    | Some (CicTextualParser0.VarUri uri) -> uri
125    | Some _ -> raise TheLeftHandSideOfAnExplicitNamedSubstitutionMustBeAVariable
126  ;;
127
128  let indty_uri_of_id id interp =
129   match interp id with
130      None -> raise (UnknownIdentifier id)
131    | Some (CicTextualParser0.IndTyUri (uri,tyno)) -> (uri,tyno)
132    | Some _ -> raise InductiveTypeURIExpected
133  ;;
134 %}
135 %token <string> ID
136 %token <int> META
137 %token <int> NUM
138 %token <UriManager.uri> CONURI
139 %token <UriManager.uri> VARURI
140 %token <UriManager.uri * int> INDTYURI
141 %token <UriManager.uri * int * int> INDCONURI
142 %token ALIAS
143 %token LPAREN RPAREN PROD LAMBDA COLON DOT SET PROP TYPE CAST IMPLICIT NONE
144 %token LETIN FIX COFIX SEMICOLON LCURLY RCURLY CASE ARROW LBRACKET RBRACKET EOF
145 %right ARROW
146 %start main
147 %type <string list * ((string -> CicTextualParser0.uri option) -> Cic.term)> main
148 %%
149 main:
150  expr EOF { $1 }
151 ;
152 expr2:
153    CONURI exp_named_subst
154    { let dom,mk_exp_named_subst = deoptionize_exp_named_subst $2 in
155       dom, function interp -> term_of_con_uri $1 (mk_exp_named_subst interp)
156    }
157  | VARURI exp_named_subst
158    { let dom,mk_exp_named_subst = deoptionize_exp_named_subst $2 in
159       dom, function interp -> term_of_var_uri $1 (mk_exp_named_subst interp)
160    }
161  | INDTYURI exp_named_subst
162    { let dom,mk_exp_named_subst = deoptionize_exp_named_subst $2 in
163       dom, function interp -> term_of_indty_uri $1 (mk_exp_named_subst interp)
164    }
165  | INDCONURI exp_named_subst
166    { let dom,mk_exp_named_subst = deoptionize_exp_named_subst $2 in
167       dom, function interp -> term_of_indcon_uri $1 (mk_exp_named_subst interp)
168    }
169  | ID exp_named_subst
170    { try
171       let res =
172        Rel (get_index_in_list (Name $1) !CicTextualParser0.binders)
173       in
174        (match $2 with
175            None -> ([], function _ -> res)
176          | Some _ -> raise (ExplicitNamedSubstitutionAppliedToRel)
177        )
178      with
179       Not_found ->
180        let dom1,mk_exp_named_subst = deoptionize_exp_named_subst $2 in
181         let dom = union dom1 [$1] in
182          dom,
183           function interp ->
184            match interp $1 with
185               None  -> raise (UnknownIdentifier $1)
186             | Some uri -> term_of_uri uri (mk_exp_named_subst interp)
187    }
188  | CASE LPAREN expr COLON INDTYURI SEMICOLON expr RPAREN LCURLY branches RCURLY
189     { let dom1,mk_expr1 = $3 in
190       let dom2,mk_expr2 = $7 in
191       let dom3,mk_expr3 = $10 in
192        let dom = union dom1 (union dom2 dom3) in
193         dom,
194         function interp ->
195          MutCase
196           (fst $5,snd $5,(mk_expr2 interp),(mk_expr1 interp),(mk_expr3 interp))
197     }
198  | CASE LPAREN expr COLON ID SEMICOLON expr RPAREN LCURLY branches RCURLY
199     { let dom1,mk_expr1 = $3 in
200       let dom2,mk_expr2 = $7 in
201       let dom3,mk_expr3 = $10 in
202        let dom = union [$5] (union dom1 (union dom2 dom3)) in
203         dom,
204         function interp ->
205          let uri,typeno = indty_uri_of_id $5 interp in
206           MutCase
207            (uri,typeno,(mk_expr2 interp),(mk_expr1 interp),
208              (mk_expr3 interp))
209     }
210  | fixheader LCURLY exprseplist RCURLY
211     { let dom1,mk_fixheader = $1 in
212       let dom2,mk_exprseplist = $3 in
213        let dom = union dom1 dom2 in
214         dom,
215          function interp ->
216           let fixfunsdecls = snd (mk_fixheader interp) in
217           let fixfunsbodies = (mk_exprseplist interp) in
218            let idx =
219             let rec find idx =
220              function
221                 [] -> raise Not_found
222               | (name,_,_)::_  when name = (fst (mk_fixheader interp)) -> idx
223               | _::tl -> find (idx+1) tl
224             in
225              find 0 fixfunsdecls
226            in
227             let fixfuns =
228              List.map2 (fun (name,recindex,ty) bo -> (name,recindex,ty,bo))
229               fixfunsdecls fixfunsbodies
230             in
231              for i = 1 to List.length fixfuns do
232               CicTextualParser0.binders := List.tl !CicTextualParser0.binders
233              done ;
234              Fix (idx,fixfuns)
235     }
236  | cofixheader LCURLY exprseplist RCURLY
237     { let dom1,mk_cofixheader = $1 in
238       let dom2,mk_exprseplist = $3 in
239        let dom = union dom1 dom2 in
240         dom,
241          function interp ->
242           let cofixfunsdecls = (snd (mk_cofixheader interp)) in
243           let cofixfunsbodies = mk_exprseplist interp in
244            let idx =
245             let rec find idx =
246              function
247                 [] -> raise Not_found
248               | (name,_)::_  when name = (fst (mk_cofixheader interp)) -> idx
249               | _::tl -> find (idx+1) tl
250             in
251              find 0 cofixfunsdecls
252            in
253             let cofixfuns =
254              List.map2 (fun (name,ty) bo -> (name,ty,bo))
255               cofixfunsdecls cofixfunsbodies
256             in
257              for i = 1 to List.length cofixfuns do
258               CicTextualParser0.binders := List.tl !CicTextualParser0.binders
259              done ;
260              CoFix (idx,cofixfuns)
261     }
262  | IMPLICIT
263     { let newmeta = new_meta () in
264        let new_canonical_context = [] in
265         let irl =
266          identity_relocation_list_for_metavariable new_canonical_context
267         in
268          CicTextualParser0.metasenv :=
269           [newmeta, new_canonical_context, Sort Type ;
270            newmeta+1, new_canonical_context, Meta (newmeta,irl);
271            newmeta+2, new_canonical_context, Meta (newmeta+1,irl)
272           ] @ !CicTextualParser0.metasenv ;
273          [], function _ -> Meta (newmeta+2,irl)
274     }
275  | SET  { [], function _ -> Sort Set }
276  | PROP { [], function _ -> Sort Prop }
277  | TYPE { [], function _ -> Sort Type }
278  | LPAREN expr CAST expr RPAREN
279     { let dom1,mk_expr1 = $2 in
280       let dom2,mk_expr2 = $4 in
281        let dom = union dom1 dom2 in
282         dom, function interp -> Cast ((mk_expr1 interp),(mk_expr2 interp))
283     }
284  | META LBRACKET substitutionlist RBRACKET
285     { let dom,mk_substitutionlist = $3 in
286        dom, function interp -> Meta ($1, mk_substitutionlist interp)
287     } 
288  | LPAREN expr expr exprlist RPAREN
289     { let dom1,mk_expr1 = $2 in
290       let dom2,mk_expr2 = $3 in
291       let dom3,mk_exprlist = $4 in
292        let dom = union dom1 (union dom2 dom3) in
293         dom,
294          function interp ->
295           Appl ([mk_expr1 interp ; mk_expr2 interp]@(mk_exprlist interp))
296     }
297 ;
298 exp_named_subst :
299     { None }
300  | LCURLY named_substs RCURLY
301     { Some $2 }
302 ;
303 named_substs :
304    VARURI LETIN expr2
305     { let dom,mk_expr = $3 in
306        dom, function interp -> [$1, mk_expr interp] }
307  | ID LETIN expr2
308     { let dom1,mk_expr = $3 in
309        let dom = union [$1] dom1 in
310         dom, function interp -> [var_uri_of_id $1 interp, mk_expr interp] }
311  | VARURI LETIN expr2 SEMICOLON named_substs
312     { let dom1,mk_expr = $3 in
313       let dom2,mk_named_substs = $5 in
314        let dom = union dom1 dom2 in
315         dom, function interp -> ($1, mk_expr interp)::(mk_named_substs interp)
316     }
317  | ID LETIN expr2 SEMICOLON named_substs
318     { let dom1,mk_expr = $3 in
319       let dom2,mk_named_substs = $5 in
320        let dom = union [$1] (union dom1 dom2) in
321         dom,
322          function interp ->
323           (var_uri_of_id $1 interp, mk_expr interp)::(mk_named_substs interp)
324     }
325 ;
326 expr :
327    pihead expr
328     { CicTextualParser0.binders := List.tl !CicTextualParser0.binders ;
329       let dom1,mk_expr1 = snd $1 in
330       let dom2,mk_expr2 = $2 in
331        let dom = union dom1 dom2 in
332         dom, function interp -> Prod (fst $1, mk_expr1 interp, mk_expr2 interp)
333     }
334  | lambdahead expr
335     { CicTextualParser0.binders := List.tl !CicTextualParser0.binders ;
336       let dom1,mk_expr1 = snd $1 in
337       let dom2,mk_expr2 = $2 in
338        let dom = union dom1 dom2 in
339         dom,function interp -> Lambda (fst $1, mk_expr1 interp, mk_expr2 interp)
340     }
341  | letinhead expr
342     { CicTextualParser0.binders := List.tl !CicTextualParser0.binders ;
343       let dom1,mk_expr1 = snd $1 in
344       let dom2,mk_expr2 = $2 in
345        let dom = union dom1 dom2 in
346         dom, function interp -> LetIn (fst $1, mk_expr1 interp, mk_expr2 interp)
347     }
348  | expr2
349     { $1 }
350 ;
351 fixheader:
352    FIX ID LCURLY fixfunsdecl RCURLY
353     { let dom,mk_fixfunsdecl = $4 in
354        dom,
355         function interp ->
356          let bs =
357           List.rev_map
358            (function (name,_,_) -> Some (Name name)) (mk_fixfunsdecl interp)
359          in
360           CicTextualParser0.binders := bs@(!CicTextualParser0.binders) ;
361           $2,(mk_fixfunsdecl interp)
362     }
363 ;
364 fixfunsdecl:
365    ID LPAREN NUM RPAREN COLON expr
366     { let dom,mk_expr = $6 in
367        dom, function interp -> [$1,$3,mk_expr interp]
368     }
369  | ID LPAREN NUM RPAREN COLON expr SEMICOLON fixfunsdecl
370     { let dom1,mk_expr = $6 in
371       let dom2,mk_fixfunsdecl = $8 in
372        let dom = union dom1 dom2 in
373         dom, function interp -> ($1,$3,mk_expr interp)::(mk_fixfunsdecl interp)
374     }
375 ;
376 cofixheader:
377    COFIX ID LCURLY cofixfunsdecl RCURLY
378     { let dom,mk_cofixfunsdecl = $4 in
379        dom,
380         function interp ->
381          let bs =
382           List.rev_map
383            (function (name,_) -> Some (Name name)) (mk_cofixfunsdecl interp)
384          in
385           CicTextualParser0.binders := bs@(!CicTextualParser0.binders) ;
386           $2,(mk_cofixfunsdecl interp)
387     }
388 ;
389 cofixfunsdecl:
390    ID COLON expr
391     { let dom,mk_expr = $3 in
392        dom, function interp -> [$1,(mk_expr interp)]
393     }
394  | ID COLON expr SEMICOLON cofixfunsdecl
395     { let dom1,mk_expr = $3 in
396       let dom2,mk_cofixfunsdecl = $5 in
397        let dom = union dom1 dom2 in
398         dom, function interp -> ($1,(mk_expr interp))::(mk_cofixfunsdecl interp)
399     }
400 ;
401 pihead:
402    PROD ID COLON expr DOT
403     { CicTextualParser0.binders := (Some (Name $2))::!CicTextualParser0.binders;
404       let dom,mk_expr = $4 in
405        Cic.Name $2, (dom, function interp -> mk_expr interp)
406     }
407  | expr2 ARROW
408    { CicTextualParser0.binders := (Some Anonymous)::!CicTextualParser0.binders ;
409      let dom,mk_expr = $1 in
410       Anonymous, (dom, function interp -> mk_expr interp)
411    }
412  | LPAREN expr RPAREN ARROW
413    { CicTextualParser0.binders := (Some Anonymous)::!CicTextualParser0.binders ;
414      let dom,mk_expr = $2 in
415       Anonymous, (dom, function interp -> mk_expr interp)
416    }
417 ;
418 lambdahead:
419   LAMBDA ID COLON expr DOT
420    { CicTextualParser0.binders := (Some (Name $2))::!CicTextualParser0.binders ;
421      let dom,mk_expr = $4 in
422       Cic.Name $2, (dom, function interp -> mk_expr interp)
423    }
424 ;
425 letinhead:
426   LAMBDA ID LETIN expr DOT
427    { CicTextualParser0.binders := (Some (Name $2))::!CicTextualParser0.binders ;
428      let dom,mk_expr = $4 in
429       Cic.Name $2, (dom, function interp -> mk_expr interp)
430    }
431 ;
432 branches:
433     { [], function _ -> [] }
434  | expr SEMICOLON branches
435     { let dom1,mk_expr = $1 in
436       let dom2,mk_branches = $3 in
437        let dom = union dom1 dom2 in
438         dom, function interp -> (mk_expr interp)::(mk_branches interp)
439     }
440  | expr
441     { let dom,mk_expr = $1 in
442        dom, function interp -> [mk_expr interp]
443     }
444 ;
445 exprlist:
446     
447     { [], function _ -> [] }
448  | expr exprlist
449     { let dom1,mk_expr = $1 in
450       let dom2,mk_exprlist = $2 in
451        let dom = union dom1 dom2 in
452         dom, function interp -> (mk_expr interp)::(mk_exprlist interp)
453     }
454 ;
455 exprseplist:
456    expr
457     { let dom,mk_expr = $1 in
458        dom, function interp -> [mk_expr interp]
459     }
460  | expr SEMICOLON exprseplist
461     { let dom1,mk_expr = $1 in
462       let dom2,mk_exprseplist = $3 in
463        let dom = union dom1 dom2 in
464         dom, function interp -> (mk_expr interp)::(mk_exprseplist interp)
465     }
466 ;
467 substitutionlist:
468     { [], function _ -> [] }
469  | expr SEMICOLON substitutionlist
470     { let dom1,mk_expr = $1 in
471       let dom2,mk_substitutionlist = $3 in
472        let dom = union dom1 dom2 in
473         dom,
474          function interp ->(Some (mk_expr interp))::(mk_substitutionlist interp)
475     }
476  | NONE SEMICOLON substitutionlist
477     { let dom,mk_exprsubstitutionlist = $3 in
478        dom, function interp -> None::(mk_exprsubstitutionlist interp)
479     }