123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209(************************************************************************)(* * 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) *)(************************************************************************)openUnifyopenRulesopenCErrorsopenUtilopenEConstropenVarsopenTacmachopenTacticsopenTacticalsopenProofview.NotationsopenReductionopsopenFormulaopenSequentopenNamesopenContext.Rel.Declarationletcompare_instanceinst1inst2=letcmpc1c2=Constr.compare(EConstr.Unsafe.to_constrc1)(EConstr.Unsafe.to_constrc2)inmatchinst1,inst2withPhantom(d1),Phantom(d2)->(cmpd1d2)|Real(i1,n1),Real(i2,n2)->let(m1,c1)=Unify.Item.repri1inlet(m2,c2)=Unify.Item.repri2in((-)=?(-)==?cmp)m2m1n1n2c1c2|Phantom_,Real(i,_)->ifUnify.Item.is_groundithen-1else1|Real(i,_),Phantom_->ifUnify.Item.is_groundithen1else-1typeany_identifier=AnyId:'aidentifier->any_identifierletcompare_grid1id2=matchid1,id2with|AnyIdGoalId,AnyIdGoalId->0|AnyIdGoalId,AnyId(FormulaId_)->1|AnyId(FormulaId_),AnyIdGoalId->-1|AnyId(FormulaIdid1),AnyId(FormulaIdid2)->GlobRef.UserOrd.compareid1id2moduleOrderedInstance=structtypet=Unify.instance*any_identifierletcompare(inst1,id1)(inst2,id2)=(compare_instance=?compare_gr)inst2inst1id2id1(* we want a __decreasing__ total order *)endmoduleIS=Set.Make(OrderedInstance)letdo_sequentenvsigmasetreftrividseqidomatoms=letflag=reftrueinletphref=reftrivinletdo_atomsa1a2=letdo_pairt1t2=matchunif_atoms(Sequent.stateseq)envsigmaidomt1t2withNone->()|Some(Phantom_)->phref:=true|Somec->flag:=false;setref:=IS.add(c,id)!setrefinList.iter(funt->List.iter(do_pairt)a2.negative)a1.positive;List.iter(funt->List.iter(do_pairt)a2.positive)a1.negativeinSequent.iter_redexes(functionAnyFormulalf->do_atomsatomslf.atoms)seq;do_atomsatoms(Sequent.make_simple_atomsseq);!flag&&!phrefletmatch_one_quantified_hyp(typea)envsigmasetrefseq(lf:aFormula.t)=matchlf.patwithLeftPattern(Lforall(i,dom,triv))|RightPattern(Rexists(i,dom,triv))->ifdo_sequentenvsigmasetreftriv(AnyIdlf.id)seqidomlf.atomsthensetref:=IS.add((Phantomdom),AnyIdlf.id)!setref|_->anomaly(Pp.str"can't happen.")letgive_instancesenvsigmalfseq=letsetref=refIS.emptyinlet()=List.iter(functionAnyFormulaf->match_one_quantified_hypenvsigmasetrefseqf)lfinIS.elements!setref(* collector for the engine *)letreccollect_quantifiedenvsigmaseq=trylethd,seq1=take_formulaenvsigmaseqinletAnyFormulahd0=hdin(matchhd0.patwithLeftPattern(Lforall(_,_,_))|RightPattern(Rexists(_,_,_))->let(q,seq2)=collect_quantifiedenvsigmaseq1in((hd::q),seq2)|_->[],seq)withHeap.EmptyHeap->[],seq(* open instances processor *)letdummy_bvid=Id.of_string"x"letmk_open_instanceenvsigmaididcc=let(m,t)=Item.reprcinletvar_id=lettyp=Retyping.get_type_ofenvsigmaidcin(* since we know we will get a product,
reduction is not too expensive *)let(nam,_,_)=destProdsigma(whd_allenvsigmatyp)inmatchnam.Context.binder_namewith|Nameid->id|Anonymous->dummy_bvidinletrevt=substl(List.initm(funi->mkRel(m-i)))tinletrecauxnavoidenvsigmadecls=ifInt.equaln0thensigma,declselseletnid=fresh_id_in_envavoidvar_idenvinlet(sigma,(c,s))=Evarutil.new_type_evarenvsigmaEvd.univ_flexibleinletdecl=LocalAssum(Context.make_annot(Namenid)(ESorts.relevance_of_sorts),c)inaux(n-1)(Id.Set.addnidavoid)(EConstr.push_reldeclenv)sigma(decl::decls)inletsigma,decls=auxmId.Set.emptyenvsigma[]in(sigma,decls,revt)(* tactics *)letleft_instance_tac~flags(inst,id)continueseq=letopenEConstrinProofview.Goal.enterbeginfungl->letsigma=projectglinletenv=Proofview.Goal.envglinmatchinstwithPhantomdom->iflookupenvsigma(id,None)seqthentclFAIL(Pp.str"already done")elsetclTHENS(cutdom)[tclTHENLIST[introf;(pf_constr_of_globalid>>=funidc->Proofview.Goal.enterbeginfungl->letid0=List.nth(pf_ids_of_hypsgl)0inGeneralize.generalize[mkApp(idc,[|mkVarid0|])]end);introf;tclSOLVE[wrap~flags1falsecontinue(deepen(recordenv(id,None)seq))]];tclTRYassumption]|Real(c,_)->iflookupenvsigma(id,Somec)seqthentclFAIL(Pp.str"already done")elseletspecial_generalize=ifnot@@Unify.Item.is_groundcthen(pf_constr_of_globalid>>=funidc->Proofview.Goal.enterbeginfungl->let(evmap,rc,ot)=mk_open_instance(pf_envgl)(projectgl)ididccinletgt=it_mkLambda_or_LetIn(mkApp(idc,[|ot|]))rcinletevmap,_=tryTyping.type_of(pf_envgl)evmapgtwithewhenCErrors.noncriticale->user_errPp.(str"Untypable instance, maybe higher-order non-prenex quantification")inProofview.tclTHEN(Proofview.Unsafe.tclEVARSevmap)(Generalize.generalize[gt])end)elsepf_constr_of_globalid>>=funidc->Generalize.generalize[mkApp(idc,[|snd@@Item.reprc|])]intclTHENLIST[special_generalize;introf;tclSOLVE[wrap~flags1falsecontinue(deepen(recordenv(id,Somec)seq))]]endletright_instance_tac~flagsinstcontinueseq=letopenEConstrinProofview.Goal.enterbeginfungl->matchinstwithPhantomdom->tclTHENS(cutdom)[tclTHENLIST[introf;Proofview.Goal.enterbeginfungl->letid0=List.nth(pf_ids_of_hypsgl)0insplit(Tactypes.ImplicitBindings[mkVarid0])end;tclSOLVE[wrap~flags0truecontinue(deepenseq)]];tclTRYassumption]|Real(c,_)->ifItem.is_groundcthen(tclTHEN(split(Tactypes.ImplicitBindings[snd@@Item.reprc]))(tclSOLVE[wrap~flags0truecontinue(deepenseq)]))elsetclFAIL(Pp.str"not implemented ... yet")endletinstance_tac~flags(hd,AnyIdid)=matchidwith|GoalId->right_instance_tac~flagshd|FormulaIdid->left_instance_tac~flags(hd,id)letquantified_tac~flagslfbacktrackcontinueseq=Proofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletinsts=give_instancesenv(projectgl)lfseqintclORELSE(tclFIRST(List.map(funinst->instance_tac~flagsinstcontinueseq)insts))backtrackend