123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172(******************************************************************************)(* *)(* The Alt-Ergo theorem prover *)(* Copyright (C) 2006-2013 *)(* *)(* Sylvain Conchon *)(* Evelyne Contejean *)(* *)(* Francois Bobot *)(* Mohamed Iguernelala *)(* Stephane Lescuyer *)(* Alain Mebsout *)(* *)(* CNRS - INRIA - Universite Paris Sud *)(* *)(* This file is distributed under the terms of the Apache Software *)(* License version 2.0 *)(* *)(* ------------------------------------------------------------------------ *)(* *)(* Alt-Ergo: The SMT Solver For Software Verification *)(* Copyright (C) 2013-2018 --- OCamlPro SAS *)(* *)(* This file is distributed under the terms of the Apache Software *)(* License version 2.0 *)(* *)(******************************************************************************)(** Integers implementation. Based on Zarith's integers **)moduleZ:NumbersInterface.ZSigwithtypet=Z.t=structtypet=Z.tletzero=Z.zeroletone=Z.oneletm_one=Z.minus_oneletcompareab=Z.compareabletcompare_to_0t=Z.signtletequalab=Z.equalabletsignt=Z.signtlethasht=Z.hashtletis_zerot=compare_to_0t=0letis_onet=equaltoneletis_m_onet=equaltm_oneletaddab=Z.addabletsubab=Z.subabletmultab=Z.mulabletdivab=assert(not(is_zerob));Z.divabletremab=assert(not(is_zerob));Z.remabletdiv_remab=assert(not(is_zerob));Z.div_remabletminust=Z.negtletabst=Z.abstletmaxt1t2=Z.maxt1t2letfrom_intn=Z.of_intnletfrom_strings=Z.of_stringsletto_stringt=Z.to_stringtletprintfmtz=Format.fprintffmt"%s"(to_stringz)letmy_gcdab=ifis_zeroathenbelseifis_zerobthenaelseZ.gcdabletmy_lcmab=tryletres1=Z.lcmabinassert(equalres1(div(multab)(my_gcdab)));res1withDivision_by_zero->assertfalseletto_machine_intt=trySome(Z.to_intt)withZ.Overflow->None(* These functuons are not exported, but they are used by module Q below *)letto_floatz=Z.to_floatzletfdivz1z2=assert(not(is_zeroz2));Z.fdivz1z2letcdivz1z2=assert(not(is_zeroz2));Z.cdivz1z2letpowerzn=assert(n>=0);Z.powzn(* Shifts left by (n:int >= 0) bits. This is the same as t * pow(2,n) *)letshift_left=Z.shift_left(* returns sqrt truncated with the remainder. It assumes that the argument
is positive, otherwise, [Invalid_argument] is raised. *)letsqrt_rem=Z.sqrt_remlettestbitzn=assert(n>=0);Z.testbitznletnumbits=Z.numbitsend(** Rationals implementation. Based on Zarith's rationals **)moduleQ:NumbersInterface.QSigwithmoduleZ=Z=structmoduleZ=ZexceptionNot_a_floattypet=Q.tletnumt=Q.numtletdent=Q.dentletzero=Q.zeroletone=Q.oneletm_one=Q.minus_oneletcomparet1t2=Q.comparet1t2letcompare_to_0t=Q.signtletequalt1t2=Q.equalt1t2letsignt=Q.signtlethasht=13*Z.hash(numt)+23*Z.hash(dent)letis_zerot=compare_to_0t=0letis_onet=equaltoneletis_m_onet=equaltm_oneletis_intt=Z.is_one(dent)letaddt1t2=Q.addt1t2letsubt1t2=Q.subt1t2letmultt1t2=Q.mult1t2letdivt1t2=assert(not(is_zerot2));Q.divt1t2letminust=Q.negtletabst=Q.abstletmint1t2=Q.mint1t2letmaxt1t2=Q.maxt1t2letinvt=ifZ.is_zero(numt)thenraiseDivision_by_zero;Q.invtletfrom_intn=Q.of_intnletfrom_zz=Q.makezZ.oneletfrom_zzz1z2=Q.makez1z2letfrom_strings=Q.of_stringsletfrom_floatf=iff=infinity||f=neg_infinitythenraiseNot_a_float;Q.of_floatfletto_stringt=Q.to_stringtletto_zq=assert(is_intq);numqletto_floatt=(Z.to_float(numt))/.(Z.to_float(dent))letprintfmtq=Format.fprintffmt"%s"(to_stringq)letfloort=from_z(Z.fdiv(numt)(dent))letceilingt=from_z(Z.cdiv(numt)(dent))letpowertn=letabs_n=Pervasives.absninletnum_pow=Z.power(numt)abs_ninletden_pow=Z.power(dent)abs_ninifn>=0thenfrom_zznum_powden_powelsefrom_zzden_pownum_powletmodulot1t2=assert(is_intt1&&is_intt2);from_zz(Z.rem(numt1)(numt2))Z.one(* converts the argument to an integer by truncation. *)lettruncate=Q.to_bigintletmult_2exp=Q.mul_2expletdiv_2exp=Q.div_2expend