我最近开始使用Z3,目前存在使用子逗号值对实数进行错误计算的问题。我使用SMT2在文本文件中定义问题并将其提供给Z3(版本4.3)。
我使用非线性算法来解决调度问题,如果任务执行时间,周期等是自然数,例如1.0,2.0,则该问题很好地解决。而例如0.3或0.2不会返回正确的结果。好像会出现转换错误。可以针对不同的子逗号值重现该问题。目前的解决方法是将常数乘以10 ^ x以消除所有子逗号值,然后问题解决得很好。
我可以为以下代码产生错误:(它为w_t1_t2返回一个不正确的值)
(set-option :produce-models true)
(declare-const s_t2 Real)
(declare-const s_t1 Real)
(declare-const w_t1_t2 Real)
(declare-const t_f1 Real)
(assert (<= 0 s_t2 5.0))
(assert (<= 0 s_t1 5.0))
(assert (xor (<= (+ (+ 0.0 s_t2) 0.3) (+ 0.0 s_t1)) (<= (+ (+ 0.0 s_t1) 0.2) (+ 0.0 s_t2))))
(assert (xor (<= (+ (+ 0.0 s_t2) 0.3) (+ 5.0 s_t1)) (<= (+ (+ 5.0 s_t1) 0.2) (+ 0.0 s_t2))))
(assert (xor (<= (+ (+ 5.0 s_t2) 0.3) (+ 0.0 s_t1)) (<= (+ (+ 0.0 s_t1) 0.2) (+ 5.0 s_t2))))
(assert (xor (<= (+ (+ 5.0 s_t2) 0.3) (+ 5.0 s_t1)) (<= (+ (+ 5.0 s_t1) 0.2) (+ 5.0 s_t2))))
(assert (<= 0 w_t1_t2 5.0))
(assert (xor (= w_t1_t2 (- s_t2 (mod (+ s_t1 0.2) 5.0))) (= w_t1_t2 (- (+ s_t2 5.0) (mod (+ s_t1 0.2) 5.0)))))
(assert (<= (+ 0.3 0.2) t_f1 6.0))
(assert (>= t_f1 (+ (+ 0.3 0.2) (+ w_t1_t2))))
(check-sat)
(get-value ( s_t2 s_t1 w_t1_t2 t_f1))
(exit)
该代码计算两个周期性任务t1和t2相互通信的可行开始时间。受到定义的截止期限的约束并阻止两个任务相交。 s_t1和s_t2分别代表t1和t2的开始时间,w_t1_t2是等待时间,t_f1代表从t1开始到t2完成的截止时间。期限为5.0,截止日期为6.0,执行时间分别为t1和t2的0.2和0.3,这里得到的结果是: s_t1 = 0.3,s_t2 = 0(等于5.0定期执行)和w_t1_t2 = 5.0。 但是,手动计算w_t1_t2会导致:w_t1_t2 = s_t2 + period - (s_t2 + execution_time_t1)= 0.0 +5.0 - (0.3 + 0.2)= 4.5
如果相反,0.2和0.3将被0.1和2.0替换,结果是正确的。
我错过了什么吗?您对如何解决这个问题有任何建议吗?
谢谢你,最诚挚的问候, 弗洛里安
答案 0 :(得分:1)
等式:
(= w_t1_t2 (- (+ s_t2 5.0) (mod (+ s_t1 0.2) 5.0)))
满意。您正在使用运算符“mod”,它是为整数定义的。 Z3将Reals的强制转换为整数,使得(+ s_t1 0.2)成为最低点。