Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file bool_encode.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 Applicative Encoding} *)openLogtkopenLibzipperpositionmoduleT=TypedSTermletsection=Util.Section.make~parent:Const.section"bool_encode"letenabled_=reffalselet(==>)=T.Ty.(==>)letdeclidty=Statement.ty_decl~proof:Proof.Step.trivialidtyletbool_clone_id=ID.make"$_bool"letbool_clone_ty=T.const~ty:T.tTypebool_clone_idletbool_clone_tydecl=declbool_clone_idbool_clone_tylettrue_clone_id=ID.make"$_true"lettrue_term=T.const~ty:bool_clone_tytrue_clone_idlettrue_clone_tydecl=decltrue_clone_idbool_clone_tyletfalse_clone_id=ID.make"$_false"letfalse_term=T.const~ty:bool_clone_tyfalse_clone_idletfalse_clone_tydecl=declfalse_clone_idbool_clone_tyletand_id=ID.make"$_and"letand_type=[bool_clone_ty;bool_clone_ty]==>bool_clone_tyletand_term=T.const~ty:and_typeand_idletand_clone_tydecl=decland_idand_typeletor_id=ID.make"$_or"letor_type=[bool_clone_ty;bool_clone_ty]==>bool_clone_tyletor_term=T.const~ty:or_typeor_idletor_clone_tydecl=declor_idor_typeletnot_id=ID.make"$_not"letnot_type=[bool_clone_ty]==>bool_clone_tyletnot_term=T.const~ty:not_typenot_idletnot_clone_tydecl=declnot_idnot_typeletimpl_id=ID.make"$_impl"letimpl_type=[bool_clone_ty;bool_clone_ty]==>bool_clone_tyletimpl_term=T.const~ty:impl_typeimpl_idletimpl_clone_tydecl=declimpl_idimpl_typeletequiv_id=ID.make"$_equiv"letequiv_type=[bool_clone_ty;bool_clone_ty]==>bool_clone_tyletequiv_term=T.const~ty:equiv_typeequiv_idletequiv_clone_tydecl=declequiv_idequiv_typeletxor_id=ID.make"$_xor"letxor_type=[bool_clone_ty;bool_clone_ty]==>bool_clone_tyletxor_term=T.const~ty:xor_typexor_idletxor_clone_tydecl=declxor_idxor_typeleteq_id=ID.make"$_eq"leteq_type=letalpha=Var.make~ty:T.tType(ID.make"alpha")inletbody=[T.varalpha;T.varalpha]==>bool_clone_tyinT.Ty.close_forallbodyleteq_term=T.const~ty:eq_typeeq_idleteq_clone_tydecl=decleq_ideq_typeletneq_id=ID.make"$_neq"letneq_term=T.const~ty:eq_typeneq_idletneq_clone_tydecl=declneq_ideq_typeletforall_id=ID.make"$_forall"letforall_type=letalpha=Var.make~ty:T.tType(ID.make"alpha")inletbody=[([T.varalpha]==>bool_clone_ty)]==>bool_clone_tyinT.Ty.close_forallbodyletforall_term=T.const~ty:forall_typeforall_idletforall_clone_tydecl=declforall_idforall_typeletexists_id=ID.make"$_exists"letexists_term=T.const~ty:forall_typeexists_idletexists_clone_tydecl=declexists_idforall_typeletchoice_id=ID.make"$_choice"letchoice_type=letalpha=Var.make~ty:T.tType(ID.make"alpha")inletbody=[([T.varalpha]==>bool_clone_ty)]==>T.varalphainT.Ty.close_forallbodyletchoice_term=T.const~ty:choice_typechoice_idletchoice_clone_tydecl=declchoice_idchoice_typeletty_decls=Iter.of_list[bool_clone_tydecl;true_clone_tydecl;false_clone_tydecl;and_clone_tydecl;or_clone_tydecl;not_clone_tydecl;impl_clone_tydecl;equiv_clone_tydecl;xor_clone_tydecl;eq_clone_tydecl;neq_clone_tydecl;forall_clone_tydecl;exists_clone_tydecl;choice_clone_tydecl]letapp_boolhdargs=T.apphd~ty:bool_clone_tyargsletboolean_axioms=letbool_x=T.var(Var.make~ty:bool_clone_ty(ID.make"X"))inletbool_y=T.var(Var.make~ty:bool_clone_ty(ID.make"Y"))inletalpha_var=Var.make~ty:T.tType(ID.make"alpha")inletalpha=T.varalpha_varinletalpha_x=T.var(Var.make~ty:alpha(ID.make"X"))inletalpha_y=T.var(Var.make~ty:alpha(ID.make"Y"))inletalpha2bool_p=T.var(Var.make~ty:([alpha]==>bool_clone_ty)(ID.make"P"))in(* x = T \/ x = F *)leteither_true_or_false=[SLiteral.eqbool_xtrue_term;SLiteral.eqbool_xfalse_term]in(* T != F *)lettrue_neq_false=[SLiteral.neqtrue_termfalse_term]in(* and T x = x *)letand_true=[SLiteral.eq(app_booland_term[true_term;bool_x])bool_x]in(* and F x = F *)letand_false=[SLiteral.eq(app_booland_term[false_term;bool_x])false_term]in(* not T = F *)letnot_true=[SLiteral.eq(app_boolnot_term[true_term])false_term]in(* not F = T *)letnot_false=[SLiteral.eq(app_boolnot_term[false_term])true_term]in(* or T x = T *)letor_true=[SLiteral.eq(app_boolor_term[true_term;bool_x])true_term]in(* or F x = x *)letor_false=[SLiteral.eq(app_boolor_term[false_term;bool_x])bool_x]in(* impl T x = x *)letimpl_t=[SLiteral.eq(app_boolimpl_term[true_term;bool_x])bool_x]in(* impl F x = T *)letimpl_f=[SLiteral.eq(app_boolimpl_term[false_term;bool_x])true_term]inletequiv_def=[SLiteral.eq(app_boolequiv_term[bool_x;bool_y])(app_booland_term[app_boolimpl_term[bool_x;bool_y];app_boolimpl_term[bool_y;bool_x]])]inletxor_def=[SLiteral.eq(app_boolxor_term[bool_x;bool_y])(app_boolnot_term[app_boolequiv_term[bool_x;bool_y]])]inleteq_x_y=app_booleq_term[alpha;alpha_x;alpha_y]inletneq_x_y=app_boolneq_term[alpha;alpha_x;alpha_y]in(* x != y \/ eq x y = T *)leteq_true=[SLiteral.neqalpha_xalpha_y;SLiteral.eqeq_x_ytrue_term]in(* x = y \/ eq x y = F *)leteq_false=[SLiteral.eqalpha_xalpha_y;SLiteral.eqeq_x_yfalse_term]in(* neq x y = not (eq x y) *)letneq_is_not_eq=[SLiteral.eqneq_x_y(app_boolnot_term[eq_x_y])]inletlambda_x_true=T.close_with_vars~binder:Binder.Lambda[alpha_x]true_termin(* forall (\x. T) = T *)letforall_true=[SLiteral.eq(app_boolforall_term[alpha;lambda_x_true])true_term]in(* P = \x. T \/ forall P = F *)letforall_false=[SLiteral.eqalpha2bool_plambda_x_true;SLiteral.eq(app_boolforall_term[alpha;alpha2bool_p])false_term]in(* \x. not (P x) *)letl_not_p_x=T.close_with_vars~binder:Binder.Lambda[alpha_x](app_boolnot_term[app_boolalpha2bool_p[alpha_x]])in(* exists P = not (forall (\x. not (P x))) *)letexists_def=[SLiteral.eq(app_boolexists_term[alpha;alpha2bool_p])(app_boolnot_term[app_boolforall_term[alpha;l_not_p_x]])]in(* P X *)letp_x=app_boolalpha2bool_p[alpha_x]inletp_choice_p=app_boolalpha2bool_p[T.app~ty:alphachoice_term[alpha;alpha2bool_p]]in(* p x \/ p (choice p) *)letchoice_def=[SLiteral.eq(p_x)(false_term);SLiteral.eq(p_choice_p)(true_term);]inIter.of_list[either_true_or_false;true_neq_false;and_true;and_false;not_true;not_false;or_true;or_false;eq_true;eq_false;neq_is_not_eq;forall_true;forall_false;exists_def;impl_t;impl_f;equiv_def;xor_def;choice_def]letbool_encode_tyty_orig=letrecauxty=matchT.viewtywith|T.App(f,args)->T.app~ty:T.tType(auxf)(CCList.mapauxargs)|T.AppBuiltin(Builtin.Arrow,ret::args)->letret'=auxretinletargs'=List.mapauxargsinT.Ty.fun_args'ret'|T.AppBuiltin(f,args)->assert(f!=Builtin.Arrow);iff==Builtin.Propthenbool_clone_tyelseT.app_builtin~ty:T.tTypef(List.mapauxargs)|T.Const_->ty|T.Var_->ty|T.Bind(b,v,t)->T.bind~ty:T.tTypebv(auxt)|T.Meta_->failwith"Not implemented: Meta"|T.Ite(_,_,_)->failwith"Not implemented: Ite"|T.Let_->failwith"Not implemented: Let"|T.Match(_,_)->failwith"Not implemented: Match"|T.Multiset_->failwith"Not implemented: Multiset"|T.Record(_,_)->failwith"Not implemented: Record"inauxty_origletbool_encode_termt_orig=letrecauxt=letencode_varv=letty=bool_encode_ty(Var.tyv)inVar.update_tyv~f:(fun_->ty)intryifT.equal(T.ty_exnt)T.tTypethenbool_encode_tytelse(letty=bool_encode_ty(CCOpt.get_exn(T.tyt))inmatchT.viewtwith|T.Constc->T.const~tyc|T.Varv->T.var(encode_varv)|T.App(f,[])->auxf|T.App(f,args)->letf'=auxfinletargs'=List.mapauxargsinT.app~tyf'args'|T.AppBuiltin(((And|Or)asb),ts)->lethead=ifb==Andthenand_termelseor_terminbeginmatchtswith|[]->head|[x]->app_boolhead[auxx]|x::y::tts->letinit=app_boolhead[auxx;auxy]inList.fold_left(funaccarg->app_boolhead[acc;auxarg])initttsend|T.AppBuiltin(((Eq|Equiv|Neq|Xor)asb),[x;y])when(T.Ty.is_prop(T.ty_exnx))->assert(T.equal(T.ty_exnx)(T.ty_exny));lethead=ifb=Equiv||b=Eqthenequiv_termelsexor_terminletx=auxxandy=auxyinapp_boolhead[x;y]|T.AppBuiltin(((Eq|Neq)asb),([x;y]|[_;x;y]))->assert(T.equal(T.ty_exnx)(T.ty_exny));lethead=ifb=Eqtheneq_termelseneq_terminletx=auxxandy=auxyinletty_arg=T.ty_exnxinapp_boolhead[ty_arg;x;y]|T.AppBuiltin((Imply),[x;y])->assert(T.equal(T.ty_exnx)(T.ty_exny));letx=auxxandy=auxyinapp_boolimpl_term[x;y]|T.AppBuiltin(((ForallConst|ExistsConst)asb),([x]|[_;x]))->letx=auxxinlet_,args,_=T.Ty.unfold(T.ty_exnx)inassert(List.lengthargs=1);letty_arg=List.hdargsinlethead=ifb=ForallConstthenforall_termelseexists_terminapp_boolhead[ty_arg;x]|T.AppBuiltin(Not,l)->app_boolnot_term(List.mapauxl)|T.AppBuiltin(True,[])->true_term|T.AppBuiltin(False,[])->false_term|T.AppBuiltin(f,ts)->assert(not((T.equaltT.Form.true_)||(T.equaltT.Form.false_)));T.app_builtin~tyf(List.mapauxts)|T.Bind(Binder.Lambda,var,body)->letvar'=encode_varvarinletbody'=auxbodyinletty=bool_encode_ty(CCOpt.get_exn(T.tyt))inT.bind~tyBinder.Lambdavar'body'|T.Bind(((Forall|Existsasb)),x,body)->lethead=ifb=Forallthenforall_termelseexists_terminletx=encode_varxinletty_arg=Var.tyxinletfun_body=T.close_with_vars~binder:Binder.Lambda[T.varx](auxbody)inapp_boolhead[ty_arg;fun_body]|_->failwith"Not implemented: Other kind of term")withInvalid_argumentty_err->leterr=CCFormat.sprintf"Subterm @[%a@]:@[%a@] of @[%a@] cannot be encoded because of type error: @[%s@]"T.pptT.pp(T.ty_exnt)T.ppt_origty_errinifCCString.prefix~pre:"type"ty_errtheninvalid_argerrelseinvalid_argty_errinletres=auxt_originUtil.debugf~section1"Encoded term @[%a@] into @[%a@]"(funk->kT.ppt_origT.ppres);resletbool_encode_litlit=matchlitwith|SLiteral.True->SLiteral.eqtrue_termtrue_term|False->SLiteral.neqtrue_termtrue_term|Atom(atom,sign)->letmk_equ_lit=ifsignthenSLiteral.eqelseSLiteral.neqinletencoded_atom=bool_encode_termatominassert(T.equal(T.ty_exntrue_term)(T.ty_exnencoded_atom));mk_equ_lit(bool_encode_termatom)true_term|Eq_|Neq_->SLiteral.mapbool_encode_termlit(** Encode a clause *)letbool_encode_litslits=List.mapbool_encode_litlitsexceptionE_iof((T.tSLiteral.t)list,T.t,T.t)Statement.tletpp_inpp_fpp_tpp_ty=function|Output_format.O_zf->Statement.ZF.pppp_fpp_tpp_ty|Output_format.O_tptp->Statement.TPTP.pppp_fpp_tpp_ty|Output_format.O_normal->Statement.pppp_fpp_tpp_ty|Output_format.O_none->CCFormat.silentletpp_clause_ino=letpp_t=T.pp_inoinpp_in(Util.pp_list~sep:" ∨ "(SLiteral.pp_inopp_t))pp_tpp_toletres_tc=Proof.Result.make_tc~of_exn:(functionE_ic->Somec|_->None)~to_exn:(funi->E_ii)~compare:compare~pp_in:pp_clause_in~is_stmt:true~name:Statement.name~to_form:(fun~ctxst->letconv_c(c:(T.tSLiteral.t)list):_=c|>List.mapSLiteral.to_form|>T.Form.or_inStatement.Seq.formsst|>Iter.mapconv_c|>Iter.to_list|>T.Form.and_)()(** encode a statement *)letbool_encode_stmtstmt=letas_proof=Proof.S.mk(Statement.proof_stepstmt)(Proof.Result.makeres_tcstmt)inletproof=Proof.Step.esa~rule:(Proof.Rule.mk"bool_encode")[as_proof|>Proof.Parent.from]inletres=matchStatement.viewstmtwith|Statement.Data_->failwith"Not implemented: Data"|Statement.Lemma_->failwith"Not implemented: Lemma"|Statement.Goallits->failwith"Not implemented: Goal"|Statement.Defdef->letmap_single=Statement.map_def~form:bool_encode_lits~term:bool_encode_term~ty:bool_encode_tyinStatement.def~proof(List.mapmap_singledef)|Statement.Rewritedef->letnew_def=Statement.map_def_rule~form:bool_encode_lits~term:bool_encode_term~ty:bool_encode_tydefinStatement.rewrite~proofnew_def|Statement.NegatedGoal(skolems,clauses)->letskolems=List.map(fun(id,ty)->(id,bool_encode_tyty))skolemsinStatement.neg_goal~proof~skolems(List.mapbool_encode_litsclauses)|Statement.Assertlits->Statement.assert_~proof(bool_encode_litslits)|Statement.TyDecl(id,ty)->Statement.ty_decl~proof:Proof.Step.trivialid(bool_encode_tyty)inresletextension=letmodifierseq=if!enabled_then(Util.debug~section2"Start boolean encoding";(* Encode statements *)letseq=Iter.mapbool_encode_stmtseqinletaxioms=Iter.map(Statement.assert_~proof:Proof.Step.trivial)boolean_axiomsin(* Add type declarations *)letseq=Iter.appendty_decls(Iter.appendaxiomsseq)in(* Add extensionality axiom *)Util.debug~section2"Finished boolean encoding";seq)elseseqinExtensions.({defaultwithname="bool_encode";post_cnf_modifiers=[modifier];})let()=Options.add_opts["--encode-booleans",Arg.Bool((:=)enabled_)," enable encoding of booleans into a fresh type"]