X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2FgTopLevel%2FproofEngine.ml;h=0cfd8f07cfe620ed9e2fe58438b6c7d97744b5c6;hb=4167cea65ca58897d1a3dbb81ff95de5074700cc;hp=f9250d3e3377c37723fcc4ae5744f422fdf0be4f;hpb=d1d5f6ee41209f05c072ba20e3cd50bc774ebff4;p=helm.git diff --git a/helm/gTopLevel/proofEngine.ml b/helm/gTopLevel/proofEngine.ml index f9250d3e3..0cfd8f07c 100644 --- a/helm/gTopLevel/proofEngine.ml +++ b/helm/gTopLevel/proofEngine.ml @@ -1,95 +1,78 @@ -type binder_type = - Declaration - | Definition -;; - -type metas_context = (int * Cic.term) list;; +(* Copyright (C) 2000, HELM Team. + * + * This file is part of HELM, an Hypertextual, Electronic + * Library of Mathematics, developed at the Computer Science + * Department, University of Bologna, Italy. + * + * HELM is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * HELM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HELM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + * + * For details, see the HELM World-Wide-Web page, + * http://cs.unibo.it/helm/. + *) -type context = (binder_type * Cic.name * Cic.term) list;; +open ProofEngineHelpers +open ProofEngineTypes -type sequent = context * Cic.term;; + (* proof assistant status *) -let proof = ref (None : (metas_context * Cic.term * Cic.term) option);; -(*CSC: Quando facciamo Clear di una ipotesi, cosa succede? *) -(* Note: the sequent is redundant: it can be computed from the type of the *) -(* metavariable and its context in the proof. We keep it just for efficiency *) -(* because computing the context of a term may be quite expensive. *) -let goal = ref (None : (int * sequent) option);; +let proof = ref (None : proof option) +let goal = ref (None : goal option) -exception NotImplemented - -(*CSC: Funzione che deve sparire!!! *) -let cic_context_of_context = - List.map - (function - Declaration,_,t -> t - | Definition,_,_ -> raise NotImplemented - ) -;; +let get_proof () = !proof;; +let set_proof p = proof := p;; -let refine_meta meta term newmetasenv = - let (metasenv,bo,ty) = - match !proof with +let get_current_status_as_xml () = + match get_proof () with None -> assert false - | Some (metasenv,bo,ty) -> metasenv,bo,ty - in - let metasenv' = newmetasenv @ (List.remove_assoc meta metasenv) in - let bo' = - let rec aux = - let module C = Cic in - function - C.Rel _ as t -> t - | C.Var _ as t -> t - | C.Meta meta' when meta=meta' -> term - | C.Meta _ as t -> t - | C.Sort _ as t -> t - | C.Implicit as t -> t - | C.Cast (te,ty) -> C.Cast (aux te, aux ty) - | C.Prod (n,s,t) -> C.Prod (n, aux s, aux t) - | C.Lambda (n,s,t) -> C.Lambda (n, aux s, aux t) - | C.LetIn (n,s,t) -> C.LetIn (n, aux s, aux t) - | C.Appl l -> C.Appl (List.map aux l) - | C.Const _ as t -> t - | C.Abst _ as t -> t - | C.MutInd _ as t -> t - | C.MutConstruct _ as t -> t - | C.MutCase (sp,cookingsno,i,outt,t,pl) -> - C.MutCase (sp,cookingsno,i,aux outt, aux t, - List.map aux pl) - | C.Fix (i,fl) -> - let substitutedfl = - List.map - (fun (name,i,ty,bo) -> (name, i, aux ty, aux bo)) - fl - in - C.Fix (i, substitutedfl) - | C.CoFix (i,fl) -> - let substitutedfl = - List.map - (fun (name,ty,bo) -> (name, aux ty, aux bo)) - fl - in - C.CoFix (i, substitutedfl) - in - aux bo - in - proof := Some (metasenv',bo',ty) + | Some (uri, metasenv, bo, ty) -> + let uri = match uri with Some uri -> uri | None -> assert false in + let currentproof = + (*CSC: Wrong: [] is just plainly wrong *) + Cic.CurrentProof (UriManager.name_of_uri uri,metasenv,bo,ty,[],[]) + in + let (acurrentproof,_,_,ids_to_inner_sorts,_,_,_) = + Cic2acic.acic_object_of_cic_object ~eta_fix:false currentproof + in + let xml, bodyxml = + match + Cic2Xml.print_object uri ~ids_to_inner_sorts + ~ask_dtd_to_the_getter:true acurrentproof + with + xml,Some bodyxml -> xml,bodyxml + | _,None -> assert false + in + (xml, bodyxml) ;; -let new_meta () = - let metasenv = - match !proof with - None -> assert false - | Some (metasenv,_,_) -> metasenv - in - let rec aux = - function - None,[] -> 1 - | Some n,[] -> n - | None,(n,_)::tl -> aux (Some n,tl) - | Some m,(n,_)::tl -> if n > m then aux (Some n,tl) else aux (Some m,tl) - in - 1 + aux (None,metasenv) +let apply_tactic ~tactic = + let module PET = ProofEngineTypes in + match get_proof (),!goal with + | None,_ + | _,None -> assert false + | Some proof', Some goal' -> + let (newproof, newgoals) = PET.apply_tactic tactic (proof', goal') in + set_proof (Some newproof); + goal := + (match newgoals, newproof with + goal::_, _ -> Some goal + | [], (_,(goal,_,_)::_,_,_) -> + (* the tactic left no open goal ; let's choose the first open goal *) + (*CSC: here we could implement and use a proof-tree like notion... *) + Some goal + | _, _ -> None) ;; (* metas_in_term term *) @@ -99,26 +82,26 @@ let metas_in_term term = let module C = Cic in let rec aux = function - C.Rel _ - | C.Var _ -> [] - | C.Meta n -> [n] + C.Rel _ -> [] + | C.Meta (n,_) -> [n] | C.Sort _ - | C.Implicit -> [] + | C.Implicit _ -> [] | C.Cast (te,ty) -> (aux te) @ (aux ty) | C.Prod (_,s,t) -> (aux s) @ (aux t) | C.Lambda (_,s,t) -> (aux s) @ (aux t) | C.LetIn (_,s,t) -> (aux s) @ (aux t) | C.Appl l -> List.fold_left (fun i t -> i @ (aux t)) [] l - | C.Const _ - | C.Abst _ - | C.MutInd _ - | C.MutConstruct _ -> [] - | C.MutCase (sp,cookingsno,i,outt,t,pl) -> + | C.Var (_,exp_named_subst) + | C.Const (_,exp_named_subst) + | C.MutInd (_,_,exp_named_subst) + | C.MutConstruct (_,_,_,exp_named_subst) -> + List.fold_left (fun i (_,t) -> i @ (aux t)) [] exp_named_subst + | C.MutCase (_,_,outt,t,pl) -> (aux outt) @ (aux t) @ (List.fold_left (fun i t -> i @ (aux t)) [] pl) - | C.Fix (i,fl) -> + | C.Fix (_,fl) -> List.fold_left (fun i (_,_,ty,bo) -> i @ (aux bo) @ (aux ty)) [] fl - | C.CoFix (i,fl) -> + | C.CoFix (_,fl) -> List.fold_left (fun i (_,ty,bo) -> i @ (aux bo) @ (aux ty)) [] fl in let metas = aux term in @@ -129,7 +112,6 @@ let metas_in_term term = he::(elim_duplicates (List.filter (function el -> he <> el) tl)) in elim_duplicates metas -;; (* perforate context term ty *) (* replaces the term [term] in the proof with a new metavariable whose type *) @@ -138,121 +120,149 @@ let metas_in_term term = (* are efficiency reasons. *) let perforate context term ty = let module C = Cic in - let newmeta = new_meta () in - match !proof with - None -> assert false - | Some (metasenv,bo,gty) -> + match get_proof () with + None -> assert false + | Some (uri,metasenv,bo,gty as proof') -> + let newmeta = new_meta_of_proof proof' in (* We push the new meta at the end of the list for pretty-printing *) (* purposes: in this way metas are ordered. *) - let metasenv' = metasenv@[newmeta,ty] in - let rec aux = - function - (* Is == strong enough? *) - t when t == term -> C.Meta newmeta - | C.Rel _ as t -> t - | C.Var _ as t -> t - | C.Meta _ as t -> t - | C.Sort _ as t -> t - | C.Implicit as t -> t - | C.Cast (te,ty) -> C.Cast (aux te, aux ty) - | C.Prod (n,s,t) -> C.Prod (n, aux s, aux t) - | C.Lambda (n,s,t) -> C.Lambda (n, aux s, aux t) - | C.LetIn (n,s,t) -> C.LetIn (n, aux s, aux t) - | C.Appl l -> C.Appl (List.map aux l) - | C.Const _ as t -> t - | C.Abst _ as t -> t - | C.MutInd _ as t -> t - | C.MutConstruct _ as t -> t - | C.MutCase (sp,cookingsno,i,outt,t,pl) -> - C.MutCase (sp,cookingsno,i,aux outt, aux t, - List.map aux pl) - | C.Fix (i,fl) -> - let substitutedfl = - List.map - (fun (name,i,ty,bo) -> (name, i, aux ty, aux bo)) - fl - in - C.Fix (i, substitutedfl) - | C.CoFix (i,fl) -> - let substitutedfl = - List.map - (fun (name,ty,bo) -> (name, aux ty, aux bo)) - fl - in - C.CoFix (i, substitutedfl) - in - let bo' = aux bo in + let metasenv' = metasenv@[newmeta,context,ty] in + let irl = + CicMkImplicit.identity_relocation_list_for_metavariable context + in +(*CSC: Bug: se ci sono due term uguali nella prova dovrei bucarne uno solo!!!*) + let bo' = + ProofEngineReduction.replace (==) [term] [C.Meta (newmeta,irl)] bo + in (* It may be possible that some metavariables occurred only in *) (* the term we are perforating and they now occurs no more. We *) (* get rid of them, collecting the really useful metavariables *) (* in metasenv''. *) +(*CSC: Bug: una meta potrebbe non comparire in bo', ma comparire nel tipo *) +(*CSC: di una metavariabile che compare in bo'!!!!!!! *) let newmetas = metas_in_term bo' in let metasenv'' = - List.filter (function (n,_) -> List.mem n newmetas) metasenv' + List.filter (function (n,_,_) -> List.mem n newmetas) metasenv' in - proof := Some (metasenv'',bo',gty) ; - goal := Some (newmeta,(context,ty)) ; - newmeta -;; + set_proof (Some (uri,metasenv'',bo',gty)) ; + goal := Some newmeta + (************************************************************) (* Some easy tactics. *) (************************************************************) -exception Fail of string;; - -let intros () = - let module C = Cic in - let module R = CicReduction in - let metasenv = - match !proof with - None -> assert false - | Some (metasenv,_,_) -> metasenv - in - let (metano,context,ty) = - match !goal with - None -> assert false - | Some (metano,(context,ty)) -> metano,context,ty - in - let newmeta = new_meta () in - let rec collect_context = - function - C.Cast (te,_) -> collect_context te - | C.Prod (n,s,t) -> - let (ctx,ty,bo) = collect_context t in - ((Declaration,n,s)::ctx,ty,C.Lambda(n,s,bo)) - | C.LetIn (n,s,t) -> - let (ctx,ty,bo) = collect_context t in - ((Definition,n,s)::ctx,ty,C.LetIn(n,s,bo)) - | _ as t -> [], t, (C.Meta newmeta) - in - let revcontext',ty',bo' = collect_context ty in - let context'' = (List.rev revcontext') @ context in - refine_meta metano bo' [newmeta,ty'] ; - goal := Some (newmeta,(context'',ty')) +(* Reduces [term] using [reduction_function] in the current scratch goal [ty] *) +let reduction_tactic_in_scratch reduction_function terms ty = + let metasenv = + match get_proof () with + None -> [] + | Some (_,metasenv,_,_) -> metasenv + in + let metano,context,_ = + match !goal with + None -> assert false + | Some metano -> List.find (function (m,_,_) -> m=metano) metasenv + in + let terms' = List.map (reduction_function context) terms in + ProofEngineReduction.replace + ~equality:(==) ~what:terms ~with_what:terms' ~where:ty ;; -(* The term bo must be closed in the current context *) -let exact bo = - let module T = CicTypeChecker in - let module R = CicReduction in - let metasenv = - match !proof with - None -> assert false - | Some (metasenv,_,_) -> metasenv - in - let (metano,context,ty) = - match !goal with - None -> assert false - | Some (metano,(context,ty)) -> - assert (ty = List.assoc metano metasenv) ; - (* Invariant: context is the actual context of the meta in the proof *) - metano,context,ty - in - (*CSC: deve sparire! *) - let context = cic_context_of_context context in - if R.are_convertible (T.type_of_aux' metasenv context bo) ty then - refine_meta metano bo [] - else - raise (Fail "The type of the provided term is not the one expected.") -;; +let whd_in_scratch = reduction_tactic_in_scratch CicReduction.whd +let reduce_in_scratch = reduction_tactic_in_scratch ProofEngineReduction.reduce +let simpl_in_scratch = reduction_tactic_in_scratch ProofEngineReduction.simpl + +(************************************************************) +(* Tactics defined elsewhere *) +(************************************************************) + + (* primitive tactics *) + +let apply term = apply_tactic (PrimitiveTactics.apply_tac ~term) +let intros ?mk_fresh_name_callback () = + apply_tactic (PrimitiveTactics.intros_tac ?mk_fresh_name_callback ()) +let cut ?mk_fresh_name_callback term = + apply_tactic (PrimitiveTactics.cut_tac ?mk_fresh_name_callback ~term) +let letin ?mk_fresh_name_callback term = + apply_tactic (PrimitiveTactics.letin_tac ?mk_fresh_name_callback ~term) +let exact term = apply_tactic (PrimitiveTactics.exact_tac ~term) +let elim_intros_simpl term = + apply_tactic (PrimitiveTactics.elim_intros_simpl_tac ~term) +let change ~goal_input:what ~input:with_what = + apply_tactic (PrimitiveTactics.change_tac ~what ~with_what) + + (* structural tactics *) + +let clearbody hyp = apply_tactic (ProofEngineStructuralRules.clearbody ~hyp) +let clear hyp = apply_tactic (ProofEngineStructuralRules.clear ~hyp) + + (* reduction tactics *) + +let whd terms = + apply_tactic + (ReductionTactics.whd_tac ~also_in_hypotheses:true ~terms:(Some terms)) +let reduce terms = + apply_tactic + (ReductionTactics.reduce_tac ~also_in_hypotheses:true ~terms:(Some terms)) +let simpl terms = + apply_tactic + (ReductionTactics.simpl_tac ~also_in_hypotheses:true ~terms:(Some terms)) + +let fold_whd term = + apply_tactic + (ReductionTactics.fold_tac ~reduction:CicReduction.whd + ~also_in_hypotheses:true ~term) +let fold_reduce term = + apply_tactic + (ReductionTactics.fold_tac ~reduction:ProofEngineReduction.reduce + ~also_in_hypotheses:true ~term) +let fold_simpl term = + apply_tactic + (ReductionTactics.fold_tac ~reduction:ProofEngineReduction.simpl + ~also_in_hypotheses:true ~term) + + (* other tactics *) + +let elim_type term = apply_tactic (EliminationTactics.elim_type_tac ~term) +let ring () = apply_tactic Ring.ring_tac +let fourier () = apply_tactic FourierR.fourier_tac + +(* let auto ~dbd () = apply_tactic (AutoTactic.auto_tac ~dbd) *) +let auto ~dbd () = apply_tactic (AutoTactic.auto_tac_new ~dbd) + + +let rewrite_simpl term = apply_tactic (EqualityTactics.rewrite_simpl_tac ~term) +let rewrite_back_simpl term = apply_tactic (EqualityTactics.rewrite_back_simpl_tac ~term) +let replace ~goal_input:what ~input:with_what = + apply_tactic (EqualityTactics.replace_tac ~what ~with_what) + +let reflexivity () = apply_tactic EqualityTactics.reflexivity_tac +let symmetry () = apply_tactic EqualityTactics.symmetry_tac +let transitivity term = apply_tactic (EqualityTactics.transitivity_tac ~term) + +let exists () = apply_tactic IntroductionTactics.exists_tac +let split () = apply_tactic IntroductionTactics.split_tac +let left () = apply_tactic IntroductionTactics.left_tac +let right () = apply_tactic IntroductionTactics.right_tac + +let assumption () = apply_tactic VariousTactics.assumption_tac + +let generalize ?mk_fresh_name_callback terms = + apply_tactic (VariousTactics.generalize_tac ?mk_fresh_name_callback terms) + +let absurd term = apply_tactic (NegationTactics.absurd_tac ~term) +let contradiction () = apply_tactic NegationTactics.contradiction_tac + +let decompose ~uris_choice_callback term = + apply_tactic (EliminationTactics.decompose_tac ~uris_choice_callback term) + +let injection term = apply_tactic (DiscriminationTactics.injection_tac ~term) +let discriminate term = apply_tactic (DiscriminationTactics.discriminate_tac ~term) +let decide_equality () = apply_tactic DiscriminationTactics.decide_equality_tac +let compare term = apply_tactic (DiscriminationTactics.compare_tac ~term) + +(* +let prova_tatticali () = apply_tactic Tacticals.prova_tac +*) +