Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ol.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482[@@@ocaml.warnings"-31-32-33"](*
open Constr
open Pp
open Context
open Typing
*)(* Unique key counters *)lettotal_formula=ref0lettotal_polar=ref0lettotal_normal=ref0(* Formula, Polar Formula and Normal Formula types *)typeformula=|Variableof{id:int;unique_key:int;mutablepolar_formula:polar_formulaoption}|Negof{child:formula;unique_key:int;mutablepolar_formula:polar_formulaoption}|Orof{children:formulalist;unique_key:int;mutablepolar_formula:polar_formulaoption}|Andof{children:formulalist;unique_key:int;mutablepolar_formula:polar_formulaoption}|Literalof{b:bool;unique_key:int;mutablepolar_formula:polar_formulaoption}andpolar_formula=|PolarVariableof{id:int;polarity:bool;unique_key:int;mutableinverse:polar_formulaoption;mutablenormal_form:normal_formulaoption}|PolarAndof{children:polar_formulalist;polarity:bool;unique_key:int;mutableinverse:polar_formulaoption;mutablenormal_form:normal_formulaoption}|PolarLiteralof{b:bool;unique_key:int;mutableinverse:polar_formulaoption;mutablenormal_form:normal_formulaoption}andnormal_formula=|NormalVariableof{id:int;polarity:bool;unique_key:int;mutableinverse:normal_formulaoption;mutableformulaP:formulaoption;mutableformulaN:formulaoption;lt_cache:(int,bool)Hashtbl.t}|NormalAndof{children:normal_formulalist;polarity:bool;unique_key:int;mutableinverse:normal_formulaoption;mutableformulaP:formulaoption;mutableformulaN:formulaoption;lt_cache:(int,bool)Hashtbl.t}|NormalLiteralof{b:bool;unique_key:int;mutableinverse:normal_formulaoption;mutableformulaP:formulaoption;mutableformulaN:formulaoption;lt_cache:(int,bool)Hashtbl.t}(* Factory functions for formula, incrementing global counter *)letnew_variableid=incrtotal_formula;Variable{id;unique_key=!total_formula;polar_formula=None}letnew_negchild=incrtotal_formula;Neg{child;unique_key=!total_formula;polar_formula=None}letnew_orchildren=incrtotal_formula;Or{children;unique_key=!total_formula;polar_formula=None}letnew_andchildren=incrtotal_formula;And{children;unique_key=!total_formula;polar_formula=None}letnew_literalb=incrtotal_formula;Literal{b;unique_key=!total_formula;polar_formula=None}(* Factory functions for polar_formula, incrementing global counter *)letnew_p_variableidpolarity=incrtotal_polar;PolarVariable{id;polarity;unique_key=!total_polar;inverse=None;normal_form=None}letnew_p_andchildrenpolarity=incrtotal_polar;PolarAnd{children;polarity;unique_key=!total_polar;inverse=None;normal_form=None}letnew_p_literalb=incrtotal_polar;PolarLiteral{b;unique_key=!total_polar;inverse=None;normal_form=None}(* Factory functions for normal_formula, incrementing global counter *)letnew_n_variableidpolarity=incrtotal_normal;NormalVariable{id;polarity;unique_key=!total_normal;inverse=None;formulaP=None;formulaN=None;lt_cache=Hashtbl.create10}letnew_n_andchildrenpolarity=incrtotal_normal;NormalAnd{children;polarity;unique_key=!total_normal;inverse=None;formulaP=None;formulaN=None;lt_cache=Hashtbl.create10}letnew_n_literalb=incrtotal_normal;NormalLiteral{b;unique_key=!total_normal;inverse=None;formulaP=None;formulaN=None;lt_cache=Hashtbl.create10}(* Getter and Setters for formulas*)letget_keyf=matchfwith|Variablev->v.unique_key|Negneg->neg.unique_key|Oror_f->or_f.unique_key|Andand_f->and_f.unique_key|Literallit->lit.unique_keyletget_polar_formulaf=matchfwith|Variablev->v.polar_formula|Negneg->neg.polar_formula|Oror_f->or_f.polar_formula|Andand_f->and_f.polar_formula|Literallit->lit.polar_formulaletset_polar_formulafp=matchfwith|Variablev->v.polar_formula<-p|Negneg->neg.polar_formula<-p|Oror_f->or_f.polar_formula<-p|Andand_f->and_f.polar_formula<-p|Literallit->lit.polar_formula<-pletget_p_normal_formpf=matchpfwith|PolarVariablev->v.normal_form|PolarAndand_f->and_f.normal_form|PolarLiterallit->lit.normal_formletset_p_normal_formpfnf=matchpfwith|PolarVariablev->v.normal_form<-nf|PolarAndand_f->and_f.normal_form<-nf|PolarLiterallit->lit.normal_form<-nfletrecsizef=matchfwith|Variable_->1|Negneg->1+sizeneg.child|Oror_f->1+List.fold_left(funaccx->acc+sizex)0or_f.children|Andand_f->1+List.fold_left(funaccx->acc+sizex)0and_f.children|Literal_->1(* Getter and Setters for polar formulas*)letget_p_keypf=matchpfwith|PolarVariablev->v.unique_key|PolarAndand_f->and_f.unique_key|PolarLiterallit->lit.unique_keyletget_p_inverse_optionpf=matchpfwith|PolarVariablev->v.inverse|PolarAndand_f->and_f.inverse|PolarLiterallit->lit.inverseletset_p_inverse_optionpf1pf2=matchpf1with|PolarVariablev->v.inverse<-pf2|PolarAndand_f->and_f.inverse<-pf2|PolarLiterallit->lit.inverse<-pf2(* Getters and Setters for normal formulas*)letget_n_keynf=matchnfwith|NormalVariablev->v.unique_key|NormalAndand_f->and_f.unique_key|NormalLiterallit->lit.unique_keyletget_n_inverse_optionnf=matchnfwith|NormalVariablev->v.inverse|NormalAndand_f->and_f.inverse|NormalLiterallit->lit.inverseletset_n_inverse_optionnf1nf2=matchnf1with|NormalVariablev->v.inverse<-nf2|NormalAndand_f->and_f.inverse<-nf2|NormalLiterallit->lit.inverse<-nf2letget_formulaPnf=matchnfwith|NormalVariablev->v.formulaP|NormalAndand_f->and_f.formulaP|NormalLiterallit->lit.formulaPletset_formulaPnff=matchnfwith|NormalVariablev->v.formulaP<-f|NormalAndand_f->and_f.formulaP<-f|NormalLiterallit->lit.formulaP<-fletget_formulaNnf=matchnfwith|NormalVariablev->v.formulaN|NormalAndand_f->and_f.formulaN|NormalLiterallit->lit.formulaNletset_formulaNnff=matchnfwith|NormalVariablev->v.formulaN<-f|NormalAndand_f->and_f.formulaN<-f|NormalLiterallit->lit.formulaN<-fletget_lt_cachenf=matchnfwith|NormalVariablev->v.lt_cache|NormalAndand_f->and_f.lt_cache|NormalLiterallit->lit.lt_cacheletlt_cachednf1nf2=Hashtbl.find_opt(get_lt_cachenf1)(get_n_keynf2)letset_lt_cachednf1nf2b=Hashtbl.add(get_lt_cachenf1)(get_n_keynf2)b(* Pretty printers *)letrecformula_to_stringf=matchfwith|Variablev->Printf.sprintf"v_%d"v.id|Negneg->Printf.sprintf"(_neg %s)"(formula_to_stringneg.child)|Oror_f->Printf.sprintf"(_or %s)"(String.concat" "(List.mapformula_to_stringor_f.children))|Andand_f->Printf.sprintf"(_and %s)"(String.concat" "(List.mapformula_to_stringand_f.children))|Literallit->iflit.bthen"trub"else"falb"letrecpolar_formula_to_stringpf=matchpfwith|PolarVariablev->ifv.polaritythenPrintf.sprintf"Pv_(%d)"v.idelsePrintf.sprintf"!Pv_(%d)"v.id|PolarAndand_f->ifand_f.polaritythenPrintf.sprintf"PAnd(%s)"(String.concat", "(List.mappolar_formula_to_stringand_f.children))elsePrintf.sprintf"!PAnd(%s)"(String.concat", "(List.mappolar_formula_to_stringand_f.children))|PolarLiterallit->iflit.bthen"Ptrub"else"Pfalb"letrecnormal_formula_to_stringnf=matchnfwith|NormalVariablev->ifv.polaritythenPrintf.sprintf"Nv_(%d)"v.idelsePrintf.sprintf"!Nv_(%d)"v.id|NormalAndand_f->ifand_f.polaritythenPrintf.sprintf"NAnd(%s)"(String.concat", "(List.mapnormal_formula_to_stringand_f.children))elsePrintf.sprintf"!NAnd(%s)"(String.concat", "(List.mapnormal_formula_to_stringand_f.children))|NormalLiterallit->iflit.bthen"Ntrub"else"Nfalb"(* Function to convert a formula to normal form *)(* Function to polarize a formula *)letget_polar_inverse(pf:polar_formula)=matchget_p_inverse_optionpfwith|Somepf'->pf'|None->letpf'=matchpfwith|PolarVariablev->new_p_variablev.id(notv.polarity)|PolarAndand_f->new_p_andand_f.children(notand_f.polarity)|PolarLiterallit->new_p_literal(notlit.b)inset_p_inverse_optionpf(Somepf');pf'letrecpolarizefpolarity=matchget_polar_formulafwith|Somepf->ifpolaritythenpfelseget_polar_inversepf|None->letpf=matchfwith|Variablev->new_p_variablev.idpolarity|Negneg->polarizeneg.child(notpolarity)|Oror_f->new_p_and(List.map(funx->polarizexfalse)or_f.children)(notpolarity)|Andand_f->new_p_and(List.map(funx->polarizextrue)and_f.children)polarity|Literallit->new_p_literal(lit.b==polarity)inifpolaritythenset_polar_formulaf(Somepf)elseset_polar_formulaf(Some(get_polar_inversepf));pfletget_normal_inverse(nf:normal_formula)=matchget_n_inverse_optionnfwith|Somenf'->nf'|None->letnf'=matchnfwith|NormalVariablev->new_n_variablev.id(notv.polarity)|NormalAndand_f->new_n_andand_f.children(notand_f.polarity)|NormalLiterallit->new_n_literal(notlit.b)inset_n_inverse_optionnf(Somenf');set_n_inverse_optionnf'(Somenf);nf'letrecto_formula_nnf(nf:normal_formula)(positive:bool):formula=letinvnf=get_normal_inversenfinmatchget_formulaPnf,get_formulaNinvnf,get_formulaNnf,get_formulaPinvnfwith|Somef,_,_,_whenpositive->f|_,Somef,_,_whenpositive->f|_,_,Somef,_whennotpositive->f|_,_,_,Somefwhennotpositive->f|_->letr=matchnfwith|NormalVariablev->ifpositive=v.polaritythennew_variablev.idelsenew_neg(to_formula_nnfnf(notpositive))|NormalAndand_f->ifpositive=and_f.polaritythennew_and(List.map(funx->to_formula_nnfxtrue)and_f.children)elsenew_or(List.map(funx->to_formula_nnfxfalse)and_f.children)|NormalLiterallit->new_literal(positive==lit.b)inifpositivethenset_formulaPnf(Somer)elseset_formulaNnf(Somer);rletto_formula(nf:normal_formula)=to_formula_nnfnftrueletreclattices_leq(nf1:normal_formula)(nf2:normal_formula)=ifget_n_keynf1=get_n_keynf2thentrueelsematchlt_cachednf1nf2with|Someb->b|None->letr=match(nf1,nf2)with|(NormalLiterallit1,NormalLiterallit2)->notlit1.b||lit2.b|(NormalLiterallit,_)->notlit.b|(_,NormalLiterallit)->lit.b|(NormalVariablev1,NormalVariablev2)->v1.id=v2.id&&v1.polarity=v2.polarity|(_,NormalAndand_f)whenand_f.polarity->List.for_all(funx->lattices_leqnf1x)and_f.children|(NormalAndand_f,_)whennotand_f.polarity->List.for_all(funx->lattices_leq(get_normal_inversex)nf2)and_f.children|(NormalVariablev,NormalAndand_f)whennotand_f.polarity->List.exists(funx->lattices_leqnf1(get_normal_inversex))and_f.children|(NormalAndand_f,NormalVariablev)whenand_f.polarity->List.exists(funx->lattices_leqxnf2)and_f.children|(NormalAndand_f1,NormalAndand_f2)->List.exists(funx->lattices_leqxnf2)and_f1.children||List.exists(funx->lattices_leqnf1(get_normal_inversex))and_f2.children|_->raise(Failure"Impossible case")in(*set_lt_cached nf1 nf2 r;*)rletsimplify(children:normal_formulalist)(polarity:bool)=letnon_simplified=new_n_andchildrenpolarityinletrectreat_childi=matchiwith|NormalAndand_fwhenand_f.polarity->and_f.children|NormalAndand_fwhennotand_f.polarity->(ifpolaritythenlettr_ch=List.mapget_normal_inverseand_f.childreninmatchList.find_opt(funf->lattices_leqnon_simplifiedf)tr_chwith|Somevalue->treat_childvalue|None->[i]elselettr_ch=and_f.childreninmatchList.find_opt(funf->lattices_leqfnon_simplified)tr_chwith|Somevalue->treat_child(get_normal_inversevalue)|None->[i])|NormalVariablev->[i]|NormalLiterallit->[i]|_->[i]inletremaining=List.flatten(List.maptreat_childchildren)inletrecloop(acc:normal_formulalist)(rem:normal_formulalist)=matchremwith|current::tail->if(lattices_leq(new_n_and(acc@tail)true)current)then(loopacctail)elseloop(current::acc)tail|[]->accinletres=loop[]remaininginmatchreswith|[]->new_n_literalpolarity|[x]->ifpolaritythenxelseget_normal_inversex|accepted->new_n_and(List.revaccepted)polarityletcheck_for_contradiction(f:normal_formula)=matchfwith|NormalAnd(and_f)whennotand_f.polarity->List.exists(funx->lattices_leqxf)and_f.children|NormalAnd(and_f)whenand_f.polarity->letshadow_children=List.mapget_normal_inverseand_f.childreninList.exists(funx->lattices_leqfx)shadow_children|_->falseletrecpolar_to_normal_form(pf:polar_formula)=matchget_p_normal_formpfwith|Somenf->nf|None->letr=matchpfwith|PolarVariablev->ifv.polaritythennew_n_variablev.idtrueelseget_normal_inverse(polar_to_normal_form(get_polar_inversepf))|PolarAndand_f->letnew_children=List.mappolar_to_normal_formand_f.childreninletsimp=simplifynew_childrenand_f.polarityinifcheck_for_contradictionsimpthennew_n_literal(notand_f.polarity)elsesimp|PolarLiterallit->new_n_literallit.bin(*set_p_normal_form pf (Some r);*)rletreduced_form(f:formula)=letp=polarizeftrueinletnf=polar_to_normal_formpinto_formulanf(* Example usage *)(* Printing results *)letshow_ol()=leta=new_variable0inletb=new_variable1inlet_f=new_or[new_and[a;b];new_neg(new_and[a;b])]in(Printf.printf"Formula: %s\n"(formula_to_string_f));(Printf.printf"Polarized: %s\n"(polar_formula_to_string(polarize_ftrue)));(Printf.printf"Normal Form: %s\n\n"(formula_to_string(reduced_form_f)))(*
Or(And(And(And(And(Or(Neg(V_7), V_5), Or(Neg(V_7), Neg(V_8))), Or(False, V_7)), Or(And(Neg(V_8), Neg(False)), And(Neg(V_9), Neg(False)))), Or(Or(And(And(V_8, V_5), Or(Neg(V_7), V_9)), Neg(V_5)), Neg(V_9))), And(And(Or(And(And(Neg(V_7), False), Or(Neg(False), Neg(V_5))), And(And(Or(Neg(V_5), V_9), Or(Neg(V_8), Neg(V_7))), Or(V_9, False))), Or(And(Neg(V_9), Or(Neg(V_8), Neg(False))), And(And(Or(Neg(V_5), Neg(False)), Or(V_5, V_8)), Neg(V_9)))), Or(Neg(False), V_9)))
*)