123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111(******************************************************************************)(* ocplib-simplex *)(* *)(* Copyright (C) --- OCamlPro --- See README.md for information and licensing *)(******************************************************************************)openExtSigsmoduletypeSIG=sigmoduleVar:VariablesmoduleR:Coefstypettypevar_status=New|Exists|Removedvalempty:tvalis_polynomial:t->boolvalis_empty:t->boolvalreplace:Var.t->R.t->t->t*var_statusvalaccumulate:Var.t->R.t->t->t*var_statusvalappend:t->R.t->t->t*(Var.t*var_status)listvalsubst:Var.t->t->t->t*(Var.t*var_status)listvalfrom_list:(Var.t*R.t)list->tvalprint:Format.formatter->t->unitvalfold:(Var.t->R.t->'a->'a)->t->'a->'avaliter:(Var.t->R.t->unit)->t->unitvalpartition:(Var.t->R.t->bool)->t->t*tvalcompare:t->t->intvalmem:Var.t->t->boolvalequal:t->t->boolvalbindings:t->(Var.t*R.t)listvalfind:Var.t->t->R.tvalremove:Var.t->t->tendmoduleMake(Var:Variables)(R:Rationals):SIGwithmoduleVar=VarandmoduleR=R=structmoduleVar=VarmoduleR=RmoduleMV=Map.Make(Var)typet=R.tMV.ttypevar_status=New|Exists|Removedletempty=MV.emptyletfold=MV.foldletiter=MV.iterletcompare=MV.compareR.compareletpartition=MV.partitionletremove=MV.removeletfind=MV.findletbindings=MV.bindingsletequal=MV.equalR.equalletmem=MV.memletis_empty=MV.is_emptyletis_polynomialp=tryletcpt=ref0initer(fun__->incrcpt;if!cpt>1thenraiseExit)p;falsewithExit->trueletreplacevqt=ifR.is_zeroqthenMV.removevt,RemovedelseMV.addvqt,(ifMV.memvtthenExistselseNew)letaccumulatevqt=letnew_q=tryR.addq(findvt)withNot_found->qinreplacevnew_qt(* TODO: We can maybe replace mp with a list, since keys are unique ... *)letappend_auxpcoefq=fold(funxc(p,mp)->letp,x_status=accumulatex(R.multcoefc)pinp,MV.addxx_statusmp)q(p,MV.empty)letappendpcoefq=letp,mp=append_auxpcoefqinp,MV.bindingsmpletsubstvpq=tryletnew_q,modified=append_aux(removevq)(findvq)pinnew_q,MV.bindings(MV.addvRemovedmodified)withNot_found->(* This will oblige us to enforce strong invariants !!
We should know exactly where we have to substitute !! *)assertfalseletfrom_listl=List.fold_left(funp(x,c)->fst(accumulatexcp))emptylletprintfmtp=letl=MV.bindingspinmatchlwith|[]->Format.fprintffmt"(empty-poly)"|(x,q)::l->Format.fprintffmt"(%a) * %a"R.printqVar.printx;List.iter(fun(x,q)->Format.fprintffmt" + (%a) * %a"R.printqVar.printx)lend