123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 Clause context}
A clause with a "hole" in it. Filling the whole with a term [t] is called
"applying the context to [t]".
The point is to relate different applications of the same context. *)openLogtkmoduleT=TermmoduleLits=Literalstypeterm=T.ttypesubst=Subst.t(** A context is represented as a regular array of literals, containing
at least one specific variable [x], paired with this variable [x].
Applying the context is a mere substitution *)typet={lits:Literals.t;var:T.var;mutablehash:int;}typectx=tletequalc1c2=HVar.equalType.equalc1.varc2.var&&Lits.equalc1.litsc2.litsletraw_litst=t.lits(* TODO: compare types of extruded variables;
if same type, instantiate with some specific "diamond" of that type
and check for alpha-equiv *)letcomparec1c2=CCOrd.(HVar.compareType.comparec1.varc2.var<?>(Lits.compare,c1.lits,c2.lits))lethash_realc=Hash.combine342(Literals.hashc.lits)(HVar.hashc.var)lethashc=ifc.hash=~-1then(leth=hash_realcinassert(h>=0);c.hash<-h);c.hashletmake_litsvar={lits;var;hash=~-1}letmakelits~var=assert(Lits.Seq.termslits|>Iter.exists(T.var_occurs~var));make_litsvarletextractlitst=ifLits.Seq.termslits|>Iter.exists(T.subterm~sub:t)then(* create fresh var to replace [t], negative to avoid collisions later *)letvar=HVar.make_unsafe~ty:(T.tyt)~-2inletvar_t=T.varvarin(* replace [t] with [var] *)letlits=Array.map(Literal.map(funroot_t->T.replaceroot_t~old:t~by:var_t))litsinSome(make_litsvar)elseNoneletextract_exnlitst=matchextractlitstwith|None->invalid_arg"ClauseContext.extract_exn"|Somec->clettriviallitst=(* create fresh var to replace [t], negative to avoid collisions later *)letvar=HVar.make_unsafe~ty:(T.tyt)~-2inassert(not(Literals.Seq.termslits|>Iter.exists(T.subterm~sub:t)));make_litsvarlet_apply_substsubst(lits,sc)=letrenaming=Subst.Renaming.create()inArray.map(funlit->Literal.apply_substrenamingsubst(lit,sc))litsletapply{lits;var;_}t=letvar=(var:T.var:>InnerTerm.tHVar.t)inletsubst=Subst.FO.bindSubst.empty(var,0)(t,1)in_apply_substsubst(lits,0)letapply_same_scope{lits;var;_}t=letvar=(var:T.var:>InnerTerm.tHVar.t)inletsubst=Subst.FO.bindSubst.empty(var,0)(t,0)in_apply_substsubst(lits,0)let_diamond=ID.make"◇"letppoutc=letcst=T.const~ty:(HVar.tyc.var)_diamondinletlits=apply_same_scopeccstinFormat.fprintfout"[@[%a@]]"Lits.pplitsmoduleSet=CCSet.Make(structtypet=ctxletcompare=compareend)