------------------------------------------------------------------------------- |-- Module : Data.SBV.Provers.Yices-- Copyright : (c) Levent Erkok-- License : BSD3-- Maintainer : erkokl@gmail.com-- Stability : experimental-- Portability : portable---- The connection to the Yices SMT solver-----------------------------------------------------------------------------{-# LANGUAGE PatternGuards #-}moduleData.SBV.Provers.Yices(yices,timeout)whereimportData.Char(isDigit)importData.List(sortBy,isPrefixOf)importSystem.Environment(getEnv)importData.SBV.BitVectors.DataimportData.SBV.Provers.SExprimportData.SBV.SMT.SMT-- | The description of the Yices SMT solver-- The default executable is @\"yices\"@, which must be in your path. You can use the @SBV_YICES@ environment variable to point to the executable on your system.-- The default options are @\"-m -f\"@, which is valid for Yices 2 series. You can use the @SBV_YICES_OPTIONS@ environment variable to override the options.yices::SMTSolveryices=SMTSolver{name="Yices",executable="yices"-- , options = ["-tc", "-smt", "-e"] -- For Yices1,options=["-m","-f"]-- For Yices2,engine=\cfginpspgm->doexecName<-getEnv"SBV_YICES"`catch`(\_->return(executable(solvercfg)))execOpts<-(words`fmap`(getEnv"SBV_YICES_OPTIONS"))`catch`(\_->return(options(solvercfg)))letcfg'=cfg{solver=(solvercfg){executable=execName,options=execOpts}}standardSolvercfg'pgm(ProofErrorcfg)(interpretcfginps)}timeout::Int->SMTSolver->SMTSolvertimeoutns|n<=0=error$"Yices.timeout value should be > 0, received: "++shown|True=s{options=optionss++["-t",shown]}sortByNodeId::[(Int,a)]->[(Int,a)]sortByNodeId=sortBy(\(x,_)(y,_)->comparexy)interpret::SMTConfig->[NamedSymVar]->[String]->SMTResultinterpretcfg_("unsat":_)=Unsatisfiablecfginterpretcfginps("unknown":rest)=Unknowncfg$map(\(_,y)->y)$sortByNodeId$concatMap(getCounterExampleinps)restinterpretcfginps("sat":rest)=Satisfiablecfg$map(\(_,y)->y)$sortByNodeId$concatMap(getCounterExampleinps)restinterpretcfg_("timeout":_)=TimeOutcfginterpretcfg_ls=ProofErrorcfg$lsgetCounterExample::[NamedSymVar]->String->[(Int,(String,CW))]getCounterExampleinpsline|isCommentline=[]|True=eithererrextract(parseSExprline)whereerrr=error$"*** Failed to parse Yices model output from: "++"*** "++showline++"\n"++"*** Reason: "++r++"\n"isInput('s':v)|allisDigitv=letinpId::IntinpId=readvincase[(s,nm)|(s@(SW_(NodeIdn)),nm)<-inps,n==inpId]of[]->Nothing[(s,nm)]->Just(inpId,s,nm)matches->error$"SBV.Yices: Cannot uniquely identify value for "++'s':v++" in "++showmatchesisInput_=Nothingextract(S_App[S_Con"=",S_Conv,S_Numi])|Just(n,s,nm)<-isInputv=[(n,(nm,mkConstCW(hasSigns,sizeOfs)i))]extract(S_App[S_Con"=",S_Numi,S_Conv])|Just(n,s,nm)<-isInputv=[(n,(nm,mkConstCW(hasSigns,sizeOfs)i))]extract_=[]-- this is largely by observation of Yices output; not quite sure if it captures allisComment::String->BoolisComments=any(`isPrefixOf`s)prefixeswhereprefixes=["---","default"]