123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137(**************************************************************************)(* *)(* SPDX-License-Identifier LGPL-2.1 *)(* Copyright (C) *)(* CEA (Commissariat à l'énergie atomique et aux énergies alternatives) *)(* *)(**************************************************************************)type('context,'value)builtin='context->'valuelist->'valueEval.or_bottommoduleMake(Model:IEEE754.Modeling)=structincludeIEEE754.Make(Model)lettrack_variablevi=Ast_types.is_floatCil_types.(vi.vtype)letof_scalarsfkindlu=letFormatformat=format_of_fkindfkindinletlower=Exact.singletonlinletupper=Exact.singletonuinletexact=Exact.joinlowerupperinletabsolute=Absolute.zeroinletrelative=Relative.zeroinmakeexactabsoluterelativeformatletset_errors_to_zerovalue=matchformatvaluewith|`Top->value|`Value(Formatformat)->letexact=exactvalueinletabsolute=Absolute.zeroinletrelative=Relative.zeroinmakeexactabsoluterelativeformatletsqrtcontext=function|[v]->`ValueComputation.(returnv|>sqrt|>resolvecontext)|_->`Valuetopletbetween_context=function|[l;u]->`Value(joinlu|>set_errors_to_zero)|_->`Valuetopletbuiltins=[("Frama_C_double_interval",between);("sqrt",sqrt)]moduleHints=Set.Make(Scalar)letconvert_hintsfloat_hints=letfoldf=Hints.add(Scalar.of_floatf)inDatatype.Float.Set.foldfoldfloat_hintsHints.emptyletcompute_error_hints_multipliersformat=letopenScalarinlettwo=Z.of_int2inletulp=Typed_float.unit_in_the_last_place_of~formatinletulp=Model.Scalar.of_float(Typed_float.to_floatulp)inlethints=refHints.(empty|>addzero|>addulp|>addone)inletto_scalarz=Z.to_stringz|>of_stringinfori=0to6doletexponent=Z.powtwoi|>Z.to_intinlethint=Z.powtwoexponent|>to_scalarinhints:=Hints.add(ulp*hint)!hintsdone;letpositive=!hintsinletnegative=Hints.mapneg!hintsinHints.unionpositivenegativeletsimple=compute_error_hints_multipliersSingleletdouble=compute_error_hints_multipliersDoubleleterror_hints_multiplier:typef.fTyped_float.format->Hints.t=functionSingle->simple|Double->doublemoduletypeAbstraction=IEEE754.AbstractionwithmoduleScalar=ScalarandmoduleComputation=Computationtype'tabstraction=(moduleAbstractionwithtypet='t)letwiden_bound~get~choose~optimizebeforeafter=letbefore=getbeforeandafter=getafterinifnotScalar.(before=after)thenoptimize(choosebeforeafter)elseafterletlower(typet)(abstraction:tabstraction)hintsbeforeafter=letmoduleA=(valabstraction)inletchoosexy=Model.Scalar.minxyinletdecidelowert=Model.Scalar.(t<=lower)inlettopifyv=Option.value~default:Model.Scalar.neg_infvinletoptimizelower=Hints.find_last_opt(decidelower)hints|>topifyinwiden_bound~get:A.lower~choose~optimizebeforeafter|>A.singletonletupper(typet)(abstraction:tabstraction)hintsbeforeafter=letmoduleA=(valabstraction)inletchoosexy=Model.Scalar.maxxyinletdecideuppert=Model.Scalar.(upper<=t)inlettopifyv=Option.value~default:Model.Scalar.pos_infvinletoptimizeupper=Hints.find_first_opt(decideupper)hints|>topifyinwiden_bound~get:A.upper~choose~optimizebeforeafter|>A.singletonletwiden_abst(typet)(abst:tabstraction)projecthintsbeforeafter=letlower=lowerabsthints(projectbefore)(projectafter)inletupper=upperabsthints(projectbefore)(projectafter)inletmoduleA=(valabst)inA.joinlowerupperletwiden_or_tophintsbeforeafter=letopenEval.Top.Operatorsinletwidenabstprojhints=widen_abstabstprojhintsbeforeafterinlet+Formatf=formatbeforeand+Formatf'=formatafterinmatchTyped_float.same_formatff'with|No->top|YesformatwhenExact.is_included(exactafter)(exactbefore)->lethints=error_hints_multiplierformatinletabsolute=widen(moduleAbsolute)absolutehintsinletrelative=widen(moduleRelative)relativehintsinmake(exactbefore)absoluterelativeformat|Yesformat->lethints=convert_hintshintsinletabsolute=Absolute.zeroinletrelative=Relative.zeroinletexact=widen(moduleExact)exacthintsinjoinafter(makeexactabsoluterelativeformat)letwiden(_,hints)beforeafter=widen_or_tophintsbeforeafter|>Eval.Top.value~top:topend