123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)openCErrorsopenUtilopenNamesopenEConstropenVarsopenTacmachopenTacticsopenTacticalsopenProofview.NotationsopenTermopsopenFormulaopenSequentmoduleNamedDecl=Context.Named.Declarationtypetactic=unitProofview.tactictypeseqtac=(Sequent.t->tactic)->Sequent.t->tactictypelseqtac=GlobRef.t->seqtactype'awith_backtracking=tactic->'aletwrap~flagsnbcontinueseq=Proofview.Goal.enterbeginfungls->Control.check_for_interrupt();letnc=Proofview.Goal.hypsglsinletenv=pf_envglsinletsigma=projectglsinletrecauxincctx=ifi<=0thenseqelsematchncwith[]->anomaly(Pp.str"Not the expected number of hyps.")|nd::q->letid=NamedDecl.get_idndinifoccur_varenvsigmaid(pf_conclgls)||List.exists(occur_var_in_declenvsigmaid)ctxthen(aux(i-1)q(nd::ctx))elseadd_formula~flags~hint:falseenvsigma(GlobRef.VarRefid)(NamedDecl.get_typend)(aux(i-1)q(nd::ctx))inletseq1=auxnnc[]inletseq2=ifbthenadd_concl~flagsenvsigma(pf_conclgls)seq1elseseq1incontinueseq2endletclear_global=function|GlobRef.VarRefid->clear[id]|_->tclIDTAC(* connection rules *)letaxiom_tacseq=Proofview.Goal.enterbeginfungl->matchSequent.find_goal(projectgl)seqwith|gr->pf_constr_of_globalgr>>=func->exact_no_checkc|exceptionNot_found->tclFAIL(Pp.str"No axiom link")endletll_atom_tac~flagsabacktrackidcontinueseq=letopenEConstrintclIFTHENELSE(tclTHENLIST[(Proofview.tclEVARMAP>>=funsigma->letgr=tryProofview.tclUNIT(find_leftsigmaaseq)withNot_found->tclFAIL(Pp.str"No link")ingr>>=fungr->pf_constr_of_globalgr>>=funleft->pf_constr_of_globalid>>=funid->Generalize.generalize[(mkApp(id,[|left|]))]);clear_globalid;intro])(wrap~flags1falsecontinueseq)backtrack(* right connectives rules *)letand_tac~flagsbacktrackcontinueseq=tclIFTHENELSEsimplest_split(wrap~flags0truecontinueseq)backtrackletor_tac~flagsbacktrackcontinueseq=tclORELSE(any_constructorfalse(Some(tclCOMPLETE(wrap~flags0truecontinueseq))))backtrackletarrow_tac~flagsbacktrackcontinueseq=tclIFTHENELSEintro(wrap~flags1truecontinueseq)(tclORELSE(tclTHENintrof(tclCOMPLETE(wrap~flags1truecontinueseq)))backtrack)(* left connectives rules *)letleft_and_tac~flagsindbacktrackidcontinueseq=Proofview.Goal.enterbeginfungl->letn=(construct_nhyps(pf_envgl)ind).(0)intclIFTHENELSE(tclTHENLIST[(pf_constr_of_globalid>>=simplest_elim);clear_globalid;tclDOnintro])(wrap~flagsnfalsecontinueseq)backtrackendletleft_or_tac~flagsindbacktrackidcontinueseq=Proofview.Goal.enterbeginfungl->letv=construct_nhyps(pf_envgl)indinletfn=tclTHENLIST[clear_globalid;tclDOnintro;wrap~flagsnfalsecontinueseq]intclIFTHENSVELSE(pf_constr_of_globalid>>=simplest_elim)(Array.mapfv)backtrackendletleft_false_tacid=Tacticals.pf_constr_of_globalid>>=simplest_elim(* left arrow connective rules *)(* We use this function for false, and, or, exists *)letll_ind_tac~flags(ind,uasindu)largsbacktrackidcontinueseq=Proofview.Goal.enterbeginfungl->letrcs=ind_hyps(pf_envgl)(projectgl)0indulargsinletvargs=Array.of_listlargsin(* construire le terme H->B, le generaliser etc *)letmytermidci=letrc=rcs.(i)inletp=List.lengthrcinletu=EInstance.makeuinletcstr=mkApp((mkConstructU((ind,(i+1)),u)),vargs)inletvars=Array.initp(funj->mkRel(p-j))inletcapply=mkApp((liftpcstr),vars)inlethead=mkApp((liftpidc),[|capply|])inEConstr.it_mkLambda_or_LetInheadrcinletlp=Array.lengthrcsinletnewhypsidc=List.initlp(mytermidc)intclIFTHENELSE(tclTHENLIST[(pf_constr_of_globalid>>=funidc->Generalize.generalize(newhypsidc));clear_globalid;tclDOlpintro])(wrap~flagslpfalsecontinueseq)backtrackendletll_arrow_tac~flagsabcbacktrackidcontinueseq=letopenEConstrinletopenVarsinletcc=mkProd(Context.make_annotAnonymousERelevance.relevant,a,(lift1b))inletdidc=mkLambda(Context.make_annotAnonymousERelevance.relevant,b,mkApp(idc,[|mkLambda(Context.make_annotAnonymousERelevance.relevant,(lift1a),(mkRel2))|]))intclORELSE(tclTHENS(cutc)[tclTHENLIST[introf;clear_globalid;wrap~flags1falsecontinueseq];tclTHENS(cutcc)[(pf_constr_of_globalid>>=func->exact_no_checkc);tclTHENLIST[(pf_constr_of_globalid>>=funidc->Generalize.generalize[didc]);clear_globalid;introf;introf;tclCOMPLETE(wrap~flags2truecontinueseq)]]])backtrack(* quantifier rules (easy side) *)letforall_tac~flagsbacktrackcontinueseq=tclORELSE(tclIFTHENELSEintro(wrap~flags0truecontinueseq)(tclORELSE(tclTHENintrof(tclCOMPLETE(wrap~flags0truecontinueseq)))backtrack))(ifflags.qflagthentclFAIL(Pp.str"reversible in 1st order mode")elsebacktrack)letleft_exists_tac~flagsindbacktrackidcontinueseq=Proofview.Goal.enterbeginfungl->letn=(construct_nhyps(pf_envgl)ind).(0)intclIFTHENELSE(Tacticals.pf_constr_of_globalid>>=simplest_elim)(tclTHENLIST[clear_globalid;tclDOnintro;(wrap(n-1)~flagsfalsecontinueseq)])backtrackendletll_forall_tac~flagsprodbacktrackidcontinueseq=tclORELSE(tclTHENS(cutprod)[tclTHENLIST[intro;(pf_constr_of_globalid>>=funidc->Proofview.Goal.enterbeginfungls->letopenEConstrinletid0=List.nth(pf_ids_of_hypsgls)0inletterm=mkApp(idc,[|mkVar(id0)|])intclTHEN(Generalize.generalize[term])(clear[id0])end);clear_globalid;intro;tclCOMPLETE(wrap~flags1falsecontinue(deepenseq))];tclCOMPLETE(wrap~flags0truecontinue(deepenseq))])backtrack(* rules for instantiation with unification moved to instances.ml *)