以下代码介绍了使用Z3和SMT-LIB的热带算术的基本属性:
; This example illustrates basic tropical arithmetic
(define-fun tropadd ((a Real)(b Real)) Real (if (> a b)
b
a))
(define-fun tropmul ((a Real)(b Real)) Real (+ a b))
(declare-fun x () Real)
(declare-fun y () Real)
(declare-fun z () Real)
(push)
(assert(not(= (tropadd x y) (tropadd y x))))
(check-sat)
(pop)
(push)
(assert(not(= (tropmul x y) (tropmul y x))))
(check-sat)
(pop)
(push)
(assert(not(= (tropmul x (tropmul y z)) (tropmul (tropmul x y) z))))
(check-sat)
(pop)
(push)
(assert(not(= (tropadd x (tropadd y z)) (tropadd (tropadd x y) z))))
(check-sat)
(pop)
(push)
(assert(not(= (tropmul x (tropadd y z)) (tropadd (tropmul x y) (tropmul x z)))))
(check-sat)
(pop)
(push)
(assert(not(= (tropmul x 0) x)))
(check-sat)
(pop)
(push)
(assert (= (tropmul x 2) 3))
(check-sat)
(get-model)
(pop)
(push)
(assert (= (tropadd x 2) 1))
(check-sat)
(get-model)
输出结果为:
unsat
unsat
unsat
unsat
unsat
unsat
sat
(model (define-fun x () Real 1.0)
sat
(model (define-fun x () Real 1.0) )
请在线运行此代码here
此代码介绍了热带添加和热带增殖。然后证明这些操作满足:交换,联想,分配;和调制热带增殖。
为了满足热带添加的调制,有必要引入 对于所有 a ,这是一个新的符号,例如:无穷大+ a = a 。
拜托,您能教我如何在热带代码中介绍这种无限。非常感谢。
答案 0 :(得分:3)
你必须定义一个新类型,某种区别联盟包括无穷大;并扩展您的操作以涵盖这种新类型。在SMT-Lib中执行此操作的标准方法是引入未解释的排序,然后断言mul / add等的定义,作为其上的适当公理。底层求解器处理这些公理的程度真的取决于它处理量词的程度以及你抛出的问题,因为这些公理无疑会涉及量词。
另一种方法是使用更高级别的方法,例如Z3Py或SBV(Haskell绑定到Z3和其他SMT求解器)所倡导的方法,在这些方法中,您可以隐藏高层结构中的大部分机器。语言。这就是我首先要尝试的,因为当你处理很多未被解释的种类,公理等时,SMT-Lib会变得非常冗长和容易出错。