123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135(* This file is free software, part of dolmen. See file "LICENSE" for more information *)moduleE=Dolmen.Std.Expr(* Type definitions *)(* ************************************************************************* *)type'awitness=..typeany_witness=Any:_witness->any_witness[@@unboxed]moduletypeS=sigtypettype_witness+=Val:twitnessvalprint:Format.formatter->t->unitvalcompare:t->t->intvalabstract:(E.Term.Const.t->t)optionendtype'aops=(moduleSwithtypet='a)typeany_ops=Ops:_ops->any_opstypet=Value:'awitness*'aops*'a->texceptionExtraction_failedoft*any_ops(* Creating ops and values *)(* ************************************************************************* *)letops(typea)?(abstract:(E.Term.Const.t->a)option)~(compare:a->a->int)~(print:Format.formatter->a->unit)():aops=letmoduleM=structtypet=atype_witness+=Val:twitnessletprint=printletcompare=compareletabstract=abstractendin(moduleM:Swithtypet=a)letmk_ops=opslet[@inline]mk(typea)~(ops:aops)(x:a)=let(moduleV)=opsinValue(V.Val,ops,x)letdummy=letops=ops~compare~print:(funfmt()->Format.fprintffmt"()")()inmk~ops()(* Std operations *)(* ************************************************************************* *)letprintfmtt=letValue(_,(moduleV),x)=tinV.printfmtxletcomparett'=letValue(w,(moduleV),x)=tinmatcht'with|Value(V.Val,_,y)->(V.comparexy:int)|Value(w',_,_)->Stdlib.compare(Anyw)(Anyw')(* Sets/Maps *)(* ************************************************************************* *)moduleAux=structtypeaux=ttypet=auxletcompare=compareendmoduleSet=Set.Make(Aux)moduleMap=Map.Make(Aux)(* Abstract values *)(* ************************************************************************* *)moduleAbstract=structtypet=|Cstof{cst:E.Term.Const.t;}letprintfmt=function|Cst{cst}->Format.fprintffmt"%a"E.Term.Const.printcstletcomparett'=matcht,t'with|Cst{cst=c;},Cst{cst=c';}->E.Term.Const.comparecc'letops=mk_ops~compare~print()endletabstract_cstcst=mk~ops:Abstract.ops(Cst{cst;})(* Extracting values *)(* ************************************************************************* *)let[@inline]extract(typea)~(ops:aops)(t:t):aoption=let(moduleV)=opsinlet(moduleA)=Abstract.opsinmatchtwith|Value(V.Val,_,x)->Somex|Value(A.Val,_,Cst{cst})->beginmatchV.abstractwith|None->None|Somef->Some(fcst)end|_->Nonelet[@inline]extract_exn(typea)~(ops:aops)(t:t):a=let(moduleV)=opsinlet(moduleA)=Abstract.opsinmatchtwith|Value(V.Val,_,x)->x|Value(A.Val,_,Cst{cst})->beginmatchV.abstractwith|Somef->fcst|None->raise(Extraction_failed(t,(Opsops)))end|_->raise(Extraction_failed(t,(Opsops)))