我正在尝试以下在 SMT-LIB 中对扩展自然进行编码的方法(我定义了一个类似于 的数据类型Maybe Integer
):
; extended integers -- if first field is true, then the value is infinity
(declare-datatypes () ((IntX (mk-int-x (is-infty Bool) (not-infty Int)))))
; addition
(define-fun plus ((x IntX) (y IntX)) IntX
(ite (or (is-infty x) (is-infty y))
(mk-int-x true 0)
(mk-int-x false (+ (not-infty x) (not-infty y)))))
(declare-fun x () IntX)
(assert (= x (plus x (mk-int-x false 1))))
; x = x+1 when x |-> infty
(get-model)
(exit)
我将如何在 SBV 中对此进行编码?我尝试了以下方法,但这只是使 SBV 崩溃。我也不知何故怀疑这会做我想要的,但我对 SBV 的工作原理还不够熟悉。
!/usr/bin/env stack
{- stack script
--resolver nightly-2018-11-23
--package sbv
--package syb
-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Generics
import Data.SBV
data IntX = IntX (Maybe Integer) deriving (Eq, Ord, Data, Read, Show, SymWord, HasKind)
pretty :: IntX -> String
pretty = \case
IntX Nothing -> "∞"
IntX n -> show n
instance Num IntX where
(+) (IntX x) (IntX y) = IntX $ (+) <$> x <*> y
(*) (IntX x) (IntX y) = IntX $ (*) <$> x <*> y
fromInteger = IntX . Just
ex1 = sat $ do
x :: SBV IntX <- free "x"
return $ x .== x + 1
main :: IO ()
main = print =<< ex1
~/temp ✘ ./sbv.hs
sbv.hs: SBV.SMT.SMTLib2.cvtExp.sh: impossible happened; can't translate: s0 + s1
CallStack (from HasCallStack):
error, called at ./Data/SBV/SMT/SMTLib2.hs:681:13 in sbv-7.12-9AiNAYtrUhB8YA6mr6BTn4:Data.SBV.SMT.SMTLib2