Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file fool.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 boolean subterms} *)openLogtkopenLibzipperpositionmoduleT=Termtypeterm=Term.tletsection=Util.Section.make~parent:Const.section"fool"letstat_fool_param=Util.mk_stat"fool.param_step"letstat_elim_var=Util.mk_stat"fool.elim_var"letenabled_=reftruemoduletypeS=sigmoduleEnv:Env.SmoduleC:moduletypeofEnv.C(** {5 Registration} *)valsetup:unit->unitvalrw_bool_lits:Env.multi_simpl_rule(** Register rules in the environment *)endmoduleMake(E:Env.S):SwithmoduleEnv=E=structmoduleEnv=EmoduleC=Env.CmoduleCtx=Env.Ctx(* replace [sub] by [true/false] in [c], obtaining a new clause *)letfool_param_sign~subsignc=letlits=C.litsc|>Literals.map(T.replace~old:sub~by:(ifsignthenT.true_elseT.false_))|>Array.to_listinletnew_lit=Literal.mk_eqsub(ifsignthenT.false_elseT.true_)inletproof=Proof.Step.inference[C.proof_parentc]~rule:(Proof.Rule.mk"fool_param")inletnew_c=C.create~trail:(C.trailc)~penalty:(C.penaltyc)(new_lit::lits)proofinUtil.debugf~section5"... deduce `@[%a@]`"(funk->kC.ppnew_c);new_c(* TODO: do not perform this under a connective (¬, ∧) or boolean combinator *)letfool_paramc:C.tlist=letsub_terms=C.Seq.termsc|>Iter.flat_map(funt->T.Seq.subterms_deptht|>Iter.filter_map(fun(t,d)->ifd>0thenSometelseNone))|>Iter.filter(funt->Type.is_prop(T.tyt)&&T.DB.is_closedt&&beginmatchT.viewtwith|T.Const_|T.App_->true|T.AppBuiltin((Builtin.True|Builtin.False),_)->false|T.AppBuiltin(_,_)->true|T.Var_|T.DB_->false|T.Fun_->assertfalse(* by typing *)end)|>T.Set.of_iterinifnot(T.Set.is_emptysub_terms)then(Util.debugf~section5"@[<2>in clause `@[%a@]`@ possible subterms are [@[<hv>%a@]]@]"(funk->kC.ppc(T.Set.pp~pp_sep:(CCFormat.return",@,")T.pp)sub_terms););beginT.Set.to_itersub_terms|>Iter.flat_map_l(funsub->[fool_param_sign~subtruec;fool_param_sign~subfalsec])|>Iter.to_rev_list|>CCFun.tap(funl->ifl<>[]then(Util.add_statstat_fool_param(List.lengthl);Util.debugf~section4"(@[<2>fool_param@ :clause %a@ :yields (@[<hv>%a@])@])"(funk->kC.ppc(Util.pp_listC.pp)l);))end(* eliminate [P ∨ C] into [C[P := ⊥]] (and same for [¬P]) *)letfool_elim_var(c:C.t):C.tlist=C.litsc|>Iter.of_array_i|>Iter.filter_map(fun(idx,lit)->assert(Literal.no_prop_invariantlit);matchlitwith(* NOTE: -- Relies on the representation of literals -- *)|Literal.Equation(lhs,rhs,true)whenT.is_true_or_falserhs->beginmatchT.as_varlhswith|Somev->(* found var, replace it with [not sign] *)lett=ifT.equalrhsT.true_thenT.false_elseT.true_inletsubst=Subst.FO.of_list'[(v,0),(t,0)]inletnew_lits=CCArray.except_idx(C.litsc)idxinletrenaming=Subst.Renaming.create()inletnew_lits=Literal.apply_subst_listrenamingsubst(new_lits,0)inletproof=Proof.Step.inference~rule:(Proof.Rule.mk"fool.elim_var")[C.proof_parent_substrenaming(c,0)subst]inletnew_c=C.createnew_litsproof~penalty:(C.penaltyc)~trail:(C.trailc)inUtil.incr_statstat_elim_var;Util.debugf~section3"(@[elim_pred_var@ :var %a :into %B@ :clause %a@ :yield %a@])"(funk->kT.pp_varv(T.equalrhsT.true_)C.ppcC.ppnew_c);Somenew_c|_->Noneend|_->None)|>Iter.to_rev_list(* rewrite some boolean literals:
- [a ≠_o b --> a || b && (¬ a || ¬b)], i.e. exclusive or
- [(∧ a b) --> a ∧ b]
- [(∨ a b) --> a ∨ b]
*)letrw_bool_lits:E.multi_simpl_rule=func->letis_bool_valt=T.equaltT.true_||T.equaltT.false_||T.is_vart||T.is_ho_apptin(* how to build a new clause *)letmk_clits=letproof=Proof.Step.simp~rule:(Proof.Rule.mk"cnf_fool")[Proof.Parent.from@@C.proofc]inC.createlitsproof~penalty:(C.penaltyc)~trail:(C.trailc)inC.litsc|>CCArray.find_map_i(funilit->matchlitwith|Literal.Equation(a,b,false)whenType.is_prop(T.tya)&¬(is_bool_vala)&¬(is_bool_valb)->letlits=CCArray.except_idx(C.litsc)iinletc_pos=Literal.mk_truea::Literal.mk_trueb::lits|>mk_cinletc_neg=Literal.mk_falsea::Literal.mk_falseb::lits|>mk_cinSome[c_pos;c_neg]|Literal.Equation(lhs,rhs,true)when(T.equalrhsT.true_)||(T.equalrhsT.false_)->(* NOTE: based on literal representation *)(* see if there is some CNF to do here *)letsign=T.equalrhsT.true_inbeginmatchT.viewlhs,signwith|T.AppBuiltin(Builtin.And,l),true|T.AppBuiltin(Builtin.Or,l),false->letlits=CCArray.except_idx(C.litsc)iinl|>List.map(funt->Literal.mk_proptsign::lits|>mk_c)|>CCOpt.return|T.AppBuiltin(Builtin.Or,l),true|T.AppBuiltin(Builtin.And,l),false->letlits=CCArray.except_idx(C.litsc)iin(List.map(funt->Literal.mk_proptsign)l@lits)|>mk_c|>CCList.return|>CCOpt.return|T.AppBuiltin(Builtin.Eq,[_;t;u]),_->letlits=CCArray.except_idx(C.litsc)iinletlit=Literal.mk_littusigninSome[mk_c(lit::lits)]|_->Noneend|Literal.Equation(a,b,true)whenType.is_prop(T.tya)&¬(is_bool_vala)&¬(is_bool_valb)->letlits=CCArray.except_idx(C.litsc)iinletc_a_imp_b=Literal.mk_falsea::Literal.mk_trueb::lits|>mk_cinletc_b_imp_a=Literal.mk_falseb::Literal.mk_truea::lits|>mk_cinSome[c_a_imp_b;c_b_imp_a]|_->None)letsetup()=Util.debug~section1"setup fool rules";Env.add_unary_inf"fool_param"fool_param;Env.add_multi_simpl_rule~priority:5rw_bool_lits;Env.add_unary_inf"fool_elim_var"fool_elim_var;()endletextension=letregisterenv=letmoduleE=(valenv:Env.S)inletmoduleET=Make(E)inif!enabled_thenET.setup()in{Extensions.defaultwithExtensions.name="fool";env_actions=[register];}let()=Options.add_opts["--fool",Arg.Bool(funv->enabled_:=v)," enable/disable fool (first-class booleans)"];Params.add_to_modes["ho-complete-basic";"ho-pragmatic";"ho-competitive";"fo-complete-basic";"lambda-free-intensional";"lambda-free-extensional";"ho-comb-complete";"lambda-free-purify-intensional";"lambda-free-purify-extensional"](fun()->enabled_:=false);Extensions.registerextension