7 (** create a ProofEngineTypes.mk_fresh_name_type function which uses given
8 * names as long as they are available, then it fallbacks to name generation
9 * using FreshNamesGenerator module *)
11 let len = List.length names in
13 fun metasenv context name ~typ ->
14 if !count < len then begin
15 let name = Cic.Name (List.nth names !count) in
19 FreshNamesGenerator.mk_fresh_name ~subst:[] metasenv context name ~typ
21 let tactic_of_ast = function
22 | TacticAst.Intros (_, _, names) ->
23 (* TODO Zack implement intros length *)
24 PrimitiveTactics.intros_tac ~mk_fresh_name_callback:(namer_of names) ()
25 | TacticAst.Reflexivity _ -> Tactics.reflexivity
26 | TacticAst.Assumption _ -> Tactics.assumption
27 | TacticAst.Contradiction _ -> Tactics.contradiction
28 | TacticAst.Exists _ -> Tactics.exists
29 | TacticAst.Fourier _ -> Tactics.fourier
30 | TacticAst.Goal (_, n) -> Tactics.set_goal n
31 | TacticAst.Left _ -> Tactics.left
32 | TacticAst.Right _ -> Tactics.right
33 | TacticAst.Ring _ -> Tactics.ring
34 | TacticAst.Split _ -> Tactics.split
35 | TacticAst.Symmetry _ -> Tactics.symmetry
36 | TacticAst.Transitivity (_, term) -> Tactics.transitivity term
37 | TacticAst.Apply (_, term) -> Tactics.apply term
38 | TacticAst.Absurd (_, term) -> Tactics.absurd term
39 | TacticAst.Exact (_, term) -> Tactics.exact term
40 | TacticAst.Cut (_, term) -> Tactics.cut term
41 | TacticAst.Elim (_, term, _) ->
42 (* TODO Zack implement "using" argument *)
43 (* old: Tactics.elim_intros_simpl term *)
44 Tactics.elim_intros term
45 | TacticAst.ElimType (_, term) -> Tactics.elim_type term
46 | TacticAst.Replace (_, what, with_what) -> Tactics.replace ~what ~with_what
47 | TacticAst.Auto (_,num) ->
48 AutoTactic.auto_tac ~num ~dbd:(MatitaDb.instance ())
49 | TacticAst.Change (_, what, with_what, _) -> Tactics.change ~what ~with_what
51 (* TODO Zack a lot more of tactics to be implemented here ... *)
52 | TacticAst.Change_pattern of 'term pattern * 'term * 'ident option
53 | TacticAst.Change of 'term * 'term * 'ident option
54 | TacticAst.Decompose of 'ident * 'ident list
55 | TacticAst.Discriminate of 'ident
56 | TacticAst.Fold of reduction_kind * 'term
57 | TacticAst.Injection of 'ident
58 | TacticAst.LetIn of 'term * 'ident
59 | TacticAst.Reduce of reduction_kind * 'term pattern * 'ident option
60 | TacticAst.Replace_pattern of 'term pattern * 'term
62 | TacticAst.Rewrite (_,dir,t,ident) ->
64 EqualityTactics.rewrite_tac ~term:t
66 EqualityTactics.rewrite_back_tac ~term:t
69 let eval_tactical status tac =
70 let apply_tactic tactic =
72 ProofEngineTypes.apply_tactic tactic (MatitaMisc.get_proof_status status)
77 let (_,metasenv,_,_) = proof in
80 | (ng,_,_)::_ -> Incomplete_proof (proof,ng))
81 | ng::_ -> Incomplete_proof (proof, ng)
83 { status with proof_status = new_status }
85 let rec tactical_of_ast = function
86 | TacticAst.Tactic (loc, tactic) -> tactic_of_ast tactic
87 | TacticAst.Fail loc -> Tacticals.fail
88 | TacticAst.Do (loc, num, tactical) ->
89 Tacticals.do_tactic num (tactical_of_ast tactical)
90 | TacticAst.IdTac loc -> Tacticals.id_tac
91 | TacticAst.Repeat (loc, tactical) ->
92 Tacticals.repeat_tactic (tactical_of_ast tactical)
93 | TacticAst.Seq (loc, tacticals) -> (* tac1; tac2; ... *)
94 Tacticals.seq (List.map tactical_of_ast tacticals)
95 | TacticAst.Then (loc, tactical, tacticals) -> (* tac; [ tac1 | ... ] *)
96 Tacticals.thens (tactical_of_ast tactical)
97 (List.map tactical_of_ast tacticals)
98 | TacticAst.Tries (loc, tacticals) ->
100 (List.map (fun t -> "", tactical_of_ast t) tacticals)
101 | TacticAst.Try (loc, tactical) ->
102 Tacticals.try_tactic (tactical_of_ast tactical)
104 apply_tactic (tactical_of_ast tac)
106 let eval_command status cmd =
108 | TacticAst.Set (loc, name, value) -> set_option status name value
109 | TacticAst.Qed loc ->
110 let uri, metasenv, bo, ty =
111 match status.proof_status with
112 | Proof (Some uri, metasenv, body, ty) ->
113 uri, metasenv, body, ty
114 | Proof (None, metasenv, body, ty) ->
116 ("Someone allows to start a thm without giving the "^
117 "name/uri. This should be fixed!")
118 | _-> command_error "You can't qed an uncomplete theorem"
120 let suri = UriManager.string_of_uri uri in
121 if metasenv <> [] then
122 command_error "Proof not completed! metasenv is not empty!";
123 let proved_ty,ugraph =
124 CicTypeChecker.type_of_aux' [] [] bo CicUniv.empty_ugraph
127 CicReduction.are_convertible [] proved_ty ty ugraph
131 ("The type of your proof is not convertible with the "^
132 "type you've declared!");
133 MatitaLog.message (sprintf "%s defined" suri);
134 let status = MatitaSync.add_constant ~uri ~body:bo ~ty ~ugraph status in
135 {status with proof_status = No_proof }
136 | TacticAst.Inductive (loc, dummy_params, types) ->
137 (* dummy_params are not real params, it is a list of nothing, and the only
138 * semantic content is the len, that is leftno (note: leftno and pamaters
139 * have nothing in common).
143 | (name, _, _, _) :: tl -> MatitaMisc.qualify status name ^ ".ind"
146 let uri = UriManager.uri_of_string suri in
147 let leftno = List.length dummy_params in
148 let obj = Cic.InductiveDefinition (types, [], leftno, []) in
150 CicTypeChecker.typecheck_mutual_inductive_defs uri
151 (types, [], leftno) CicUniv.empty_ugraph
154 MatitaSync.add_inductive_def
155 ~uri ~types ~params:[] ~leftno ~ugraph status
157 {status with proof_status = No_proof }
158 | TacticAst.Theorem (loc, thm_flavour, Some name, ty, None) ->
160 UriManager.uri_of_string (MatitaMisc.qualify status name ^ ".con")
164 match status.proof_status with
165 | Intermediate metasenv ->
166 ((goalno, [], ty) :: metasenv) , Cic.Meta (goalno,[])
169 let initial_proof = (Some uri, metasenv, body, ty) in
170 { status with proof_status = Incomplete_proof (initial_proof,goalno)}
171 | TacticAst.Theorem (loc, thm_flavour, Some name, ty, Some body) ->
173 UriManager.uri_of_string (MatitaMisc.qualify status name ^ ".con")
175 let metasenv = MatitaMisc.get_proof_metasenv status in
176 let (body_type, ugraph) =
177 CicTypeChecker.type_of_aux' metasenv [] body CicUniv.empty_ugraph
179 let (subst, metasenv, ugraph) =
180 CicUnification.fo_unif metasenv [] body_type ty ugraph
182 if metasenv <> [] then
184 "metasenv not empty while giving a definition with body";
185 let body = CicMetaSubst.apply_subst subst body in
186 let ty = CicMetaSubst.apply_subst subst ty in
187 let status = MatitaSync.add_constant ~uri ~body ~ty ~ugraph status in
188 {status with proof_status = No_proof}
189 | TacticAst.Theorem (_, _, None, _, _) ->
190 command_error "The grammas should avoid having unnamed theorems!"
191 | TacticAst.Coercion (loc, term) -> assert false (** TODO *)
192 | TacticAst.Alias (loc, spec) ->
194 | TacticAst.Ident_alias (id,uri) ->
195 {status with aliases =
196 DisambiguateTypes.Environment.add
197 (DisambiguateTypes.Id id)
198 ("boh?",(fun _ _ _ -> CicUtil.term_of_uri uri))
200 | TacticAst.Symbol_alias (symb, instance, desc) ->
201 {status with aliases =
202 DisambiguateTypes.Environment.add
203 (DisambiguateTypes.Symbol (symb,instance))
204 (DisambiguateChoices.lookup_symbol_by_dsc symb desc)
206 | TacticAst.Number_alias (instance,desc) ->
207 {status with aliases =
208 DisambiguateTypes.Environment.add
209 (DisambiguateTypes.Num instance)
210 (DisambiguateChoices.lookup_num_by_dsc desc) status.aliases }
212 let eval_executable status ex =
214 | TacticAst.Tactical (_, tac) -> eval_tactical status tac
215 | TacticAst.Command (_, cmd) -> eval_command status cmd
216 | TacticAst.Macro (_, mac) ->
217 command_error (sprintf "The macro %s can't be in a script"
218 (TacticAstPp.pp_macro_cic mac))
220 let eval_comment status c = status
224 | TacticAst.Executable (_,ex) -> eval_executable status ex
225 | TacticAst.Comment (_,c) -> eval_comment status c
227 let disambiguate_term status term =
228 let (aliases, metasenv, cic, _) =
230 MatitaDisambiguator.disambiguate_term ~dbd:(MatitaDb.instance ())
231 ~aliases:(status.aliases) ~context:(MatitaMisc.get_proof_context status)
232 ~metasenv:(MatitaMisc.get_proof_metasenv status) term
238 match status.proof_status with
239 | No_proof -> Intermediate metasenv
240 | Incomplete_proof ((uri, _, proof, ty), goal) ->
241 Incomplete_proof ((uri, metasenv, proof, ty), goal)
242 | Intermediate _ -> Intermediate metasenv
243 | Proof _ -> assert false
248 proof_status = proof_status }
252 let disambiguate_terms status terms =
253 let term = CicAst.pack terms in
254 let status, term = disambiguate_term status term in
255 status, CicUtil.unpack term
257 let disambiguate_tactic status = function
258 | TacticAst.Transitivity (loc, term) ->
259 let status, cic = disambiguate_term status term in
260 status, TacticAst.Transitivity (loc, cic)
261 | TacticAst.Apply (loc, term) ->
262 let status, cic = disambiguate_term status term in
263 status, TacticAst.Apply (loc, cic)
264 | TacticAst.Absurd (loc, term) ->
265 let status, cic = disambiguate_term status term in
266 status, TacticAst.Absurd (loc, cic)
267 | TacticAst.Exact (loc, term) ->
268 let status, cic = disambiguate_term status term in
269 status, TacticAst.Exact (loc, cic)
270 | TacticAst.Cut (loc, term) ->
271 let status, cic = disambiguate_term status term in
272 status, TacticAst.Cut (loc, cic)
273 | TacticAst.Elim (loc, term, Some term') ->
274 let status, cic1 = disambiguate_term status term in
275 let status, cic2 = disambiguate_term status term' in
276 status, TacticAst.Elim (loc, cic1, Some cic2)
277 | TacticAst.Elim (loc, term, None) ->
278 let status, cic = disambiguate_term status term in
279 status, TacticAst.Elim (loc, cic, None)
280 | TacticAst.ElimType (loc, term) ->
281 let status, cic = disambiguate_term status term in
282 status, TacticAst.ElimType (loc, cic)
283 | TacticAst.Replace (loc, what, with_what) ->
284 let status, cic1 = disambiguate_term status what in
285 let status, cic2 = disambiguate_term status with_what in
286 status, TacticAst.Replace (loc, cic1, cic2)
287 | TacticAst.Change (loc, what, with_what, ident) ->
288 let status, cic1 = disambiguate_term status what in
289 let status, cic2 = disambiguate_term status with_what in
290 status, TacticAst.Change (loc, cic1, cic2, ident)
292 (* TODO Zack a lot more of tactics to be implemented here ... *)
293 | TacticAst.Change_pattern of 'term pattern * 'term * 'ident option
294 | TacticAst.Change of 'term * 'term * 'ident option
295 | TacticAst.Decompose of 'ident * 'ident list
296 | TacticAst.Discriminate of 'ident
297 | TacticAst.Fold of reduction_kind * 'term
298 | TacticAst.Injection of 'ident
299 | TacticAst.LetIn of 'term * 'ident
300 | TacticAst.Reduce of reduction_kind * 'term pattern * 'ident option
301 | TacticAst.Replace_pattern of 'term pattern * 'term
303 | TacticAst.Rewrite (loc,dir,t,ident) ->
304 let status, term = disambiguate_term status t in
305 status, TacticAst.Rewrite (loc,dir,term,ident)
306 | TacticAst.Intros (loc, num, names) ->
307 status, TacticAst.Intros (loc, num, names)
308 | TacticAst.Auto (loc,num) -> status, TacticAst.Auto (loc,num)
309 | TacticAst.Reflexivity loc -> status, TacticAst.Reflexivity loc
310 | TacticAst.Assumption loc -> status, TacticAst.Assumption loc
311 | TacticAst.Contradiction loc -> status, TacticAst.Contradiction loc
312 | TacticAst.Exists loc -> status, TacticAst.Exists loc
313 | TacticAst.Fourier loc -> status, TacticAst.Fourier loc
314 | TacticAst.Left loc -> status, TacticAst.Left loc
315 | TacticAst.Right loc -> status, TacticAst.Right loc
316 | TacticAst.Ring loc -> status, TacticAst.Ring loc
317 | TacticAst.Split loc -> status, TacticAst.Split loc
318 | TacticAst.Symmetry loc -> status, TacticAst.Symmetry loc
319 | TacticAst.Goal (loc, g) -> status, TacticAst.Goal (loc, g)
321 print_endline ("Not yet implemented:" ^ TacticAstPp.pp_tactic x);
324 let rec disambiguate_tactical status = function
325 | TacticAst.Tactic (loc, tactic) ->
326 let status, tac = disambiguate_tactic status tactic in
327 status, TacticAst.Tactic (loc, tac)
328 | TacticAst.Do (loc, num, tactical) ->
329 let status, tac = disambiguate_tactical status tactical in
330 status, TacticAst.Do (loc, num, tac)
331 | TacticAst.Repeat (loc, tactical) ->
332 let status, tac = disambiguate_tactical status tactical in
333 status, TacticAst.Repeat (loc, tac)
334 | TacticAst.Seq (loc, tacticals) -> (* tac1; tac2; ... *)
335 let status, tacticals = disambiguate_tacticals status tacticals in
336 let tacticals = List.rev tacticals in
337 status, TacticAst.Seq (loc, tacticals)
338 | TacticAst.Then (loc, tactical, tacticals) -> (* tac; [ tac1 | ... ] *)
339 let status, tactical = disambiguate_tactical status tactical in
340 let status, tacticals = disambiguate_tacticals status tacticals in
341 status, TacticAst.Then (loc, tactical, tacticals)
342 | TacticAst.Tries (loc, tacticals) ->
343 let status, tacticals = disambiguate_tacticals status tacticals in
344 status, TacticAst.Tries (loc, tacticals)
345 | TacticAst.Try (loc, tactical) ->
346 let status, tactical = disambiguate_tactical status tactical in
347 status, TacticAst.Try (loc, tactical)
348 | (TacticAst.IdTac _ | TacticAst.Fail _) as tac ->
351 and disambiguate_tacticals status tacticals =
352 let status, tacticals =
354 (fun (status, tacticals) tactical ->
355 let status, tac = disambiguate_tactical status tactical in
356 status, tac :: tacticals)
360 let tacticals = List.rev tacticals in
363 let disambiguate_inddef status params indTypes =
364 let add_pi binders t =
366 (fun (name, ast) acc ->
367 CicAst.Binder (`Forall, (Cic.Name name, Some ast), acc))
371 List.map (fun (name, _, typ, _) -> (name, add_pi params typ)) indTypes
373 let binders = ind_binders @ params in
375 let add_ast ast = asts := ast :: !asts in
376 let paramsno = List.length params in
377 let indbindersno = List.length ind_binders in
379 (fun (name, _, typ, constructors) ->
380 add_ast (add_pi params typ);
381 List.iter (fun (_, ast) -> add_ast (add_pi binders ast)) constructors)
383 let status, terms = disambiguate_terms status !asts in
384 let terms = ref (List.rev terms) in
386 match !terms with [] -> assert false | hd :: tl -> terms := tl; hd
390 | (name, _, _, _) :: _ -> MatitaMisc.qualify status name ^ ".ind"
394 let counter = ref 0 in
398 CicUtil.term_of_uri (sprintf "%s#xpointer(1/%d)" uri !counter))
401 let subst_mutinds = List.fold_right CicSubstitution.subst mutinds in
404 (fun acc (name, inductive, typ, constructors) ->
405 let cicTyp = get_term () in
406 let cicConstructors =
408 (fun acc (name, _) ->
410 subst_mutinds (CicUtil.strip_prods indbindersno (get_term ()))
415 (name, inductive, cicTyp, List.rev cicConstructors) :: acc)
418 let cicIndTypes = List.rev cicIndTypes in
419 status, (UriManager.uri_of_string uri, (cicIndTypes, [], paramsno))
421 let disambiguate_command status = function
422 | TacticAst.Inductive (loc, params, types) ->
423 let (status, (uri, (ind_types, vars, paramsno))) =
424 disambiguate_inddef status params types
426 let rec mk_list = function
428 | n -> ("", Cic.Rel ~-117) :: mk_list (n-1)
430 (* once we've built the cic inductive types we no longer need terms
431 corresponding to parameters, but we need the leftno, and we encode
432 it as the length of dummy_params
434 let dummy_params = mk_list paramsno in
435 status, TacticAst.Inductive (loc, dummy_params, ind_types)
436 | TacticAst.Theorem (loc, thm_flavour, name, ty, body) ->
437 let status, ty = disambiguate_term status ty in
440 | None -> status, None
442 let status, body = disambiguate_term status body in
445 status, TacticAst.Theorem (loc, thm_flavour, name, ty, body)
446 | TacticAst.Coercion (loc, term) -> assert false (** TODO *)
447 | (TacticAst.Set _ | TacticAst.Qed _) as cmd ->
449 | TacticAst.Alias _ as x -> status, x
451 let disambiguate_executable status ex =
453 | TacticAst.Tactical (loc, tac) ->
454 let status, tac = disambiguate_tactical status tac in
455 status, (TacticAst.Tactical (loc, tac))
456 | TacticAst.Command (loc, cmd) ->
457 let status, cmd = disambiguate_command status cmd in
458 status, (TacticAst.Command (loc, cmd))
459 | TacticAst.Macro (_, mac) ->
461 (sprintf ("The engine is not allowed to disambiguate any macro, "^^
462 "in particular %s") (TacticAstPp.pp_macro_ast mac))
464 let disambiguate_comment status c =
466 | TacticAst.Note (loc,n) -> status, TacticAst.Note (loc,n)
467 | TacticAst.Code (loc,ex) ->
468 let status, ex = disambiguate_executable status ex in
469 status, TacticAst.Code (loc,ex)
471 let disambiguate_statement status statement =
473 | TacticAst.Comment (loc,c) ->
474 let status, c = disambiguate_comment status c in
475 status, TacticAst.Comment (loc,c)
476 | TacticAst.Executable (loc,ex) ->
477 let status, ex = disambiguate_executable status ex in
478 status, TacticAst.Executable (loc,ex)
480 let eval_ast status ast =
481 let status,st = disambiguate_statement status ast in
482 (* this disambiguation step should be deferred to support tacticals *)
485 let eval_from_stream status str =
486 let st = CicTextualParser2.parse_statement str in
489 let eval_string status str =
490 eval_from_stream status (Stream.of_string str)
492 let default_options () =
494 StringMap.add "baseuri"
496 (Helm_registry.get "matita.baseuri" ^ Helm_registry.get "matita.owner"))
500 StringMap.add "basedir"
501 (String (Helm_registry.get "matita.basedir" ))
508 aliases = DisambiguateTypes.empty_environment;
509 proof_status = No_proof;
510 options = default_options ();