在QF_UFNRA中获取真实的小数部分

时间:2017-02-09 10:07:14

标签: z3 smt cvc4

使用smtlib我想使用QF_UFNRA制作类似模数的东西。这使我无法使用mod,to_int,to_real这样的东西。

最后,我想在以下代码中获取z的小数部分:

(set-logic QF_UFNRA)

(declare-fun z () Real)
(declare-fun z1 () Real)
(define-fun zval_1 ((x Real)) Real
         x
)
(declare-fun zval (Real) Real)

(assert (= z 1.5));
(assert (=> (and (<= 0.0 z) (< z 1.0)) (= (zval z) (zval_1 z))))
(assert (=> (>= z 1.0) (= (zval z) (zval (- z 1.0)))))
(assert (= z1 (zval z)))

当然,正如我在这里提出这个问题所暗示的那样,它没有成功。

有没有人知道如何使用逻辑QF_UFNRA将z的小数部分转换为z1?

1 个答案:

答案 0 :(得分:2)

这是一个很好的问题。不幸的是,如果您将自己限制为QF_UFNRA,那么您想要做的就是

如果你可以编码这样的功能,那么你可以决定任意丢番图方程。你只需在实数上投射一个给定的丢番图方程,计算&#34;分数&#34;这种所谓方法的真实解决方案,并断言该分数为0。由于实数是可判定的,这将为您提供丢番图方程的决策程序,实现不可能。 (这被称为希尔伯特的第10个问题。)

因此,尽管任务看起来无辜,但实际上并不可行。但这并不意味着你不能用一些扩展来编码它,并且可能让解算器成功地决定了它的实例。

如果您允许量词和递归函数

如果你允许自己使用量词和递归函数,那么你可以写:

(set-logic UFNRA)

(define-fun-rec frac ((x Real)) Real (ite (< x 1) x (frac (- x 1))))

(declare-fun res () Real)
(assert (= (frac 1.5) res))

(check-sat)
(get-value (res))

z3回应:

sat
((res (/ 1.0 2.0)))

请注意,我们使用了允许量化的UFNRA逻辑,由于使用了define-fun-rec构造,这里隐式需要量化。 (有关详细信息,请参阅SMTLib手册。)这基本上是您在问题中尝试编码的内容,而是使用递归函数定义工具而不是隐式编码。但是,在SMTLib中使用递归函数有几点需要注意:特别是,您可以编写使系统不易相容的函数。有关详细信息,请参阅http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.5-draft.pdf的第4.2.3节。

如果您可以使用QF_UFNIRA

如果您转到QF_UFNIRA,即允许混合实数和整数,则编码很简单:

(set-logic QF_UFNIRA)

(declare-fun z  () Real)
(declare-fun zF () Real)
(declare-fun zI () Int)

(assert (= z (+ zF zI)))
(assert (<= 0 zF))
(assert (< zF 1))

(assert (= z 1.5))
(check-sat)
(get-value (zF zI))

z3回应:

sat
((zF (/ 1.0 2.0))
 (zI 1))

(在zI时,您可能必须小心z < 0的计算,但这个想法是一样的。)

请注意,仅仅因为编码很简单并不意味着z3将始终能够成功回答查询。由于RealIntegerz的混合,如前所述,问题仍然不明。如果您对unknown有其他限制,则z3可能会很好地回复sin此编码。在这种特殊情况下,它恰好足够简单,因此z3能够找到一个模型。

如果您有pisin

这更像是一个思想实验,而不是一个真正的替代品。如果SMTLib允许pisin (zI * pi),那么您可以检查0是否为zI,适用于受限制的zI。对此查询的任何令人满意的模型都将确保zI为整数。然后,您可以使用此值从z中减去sin来提取小数部分。

但这是徒劳的,因为SMTLib既不允许pi也不允许sin。并且有充分的理由:可判定性将会丢失。话虽如此,也许一些勇敢的灵魂可以设计一个支持piunknown等的逻辑,并成功地正确回答了您的查询,同时当问题变得太难以返回QF_UFNIRA时解算器。非线性算法和using FluentValidation.TestHelper; using NUnit.Framework; using MyProject.Models... using MyProject... namespace MyProject.Tests.Classes.Validation { [TestFixture] public class SomeFormValidatorTest { private SomeFormValidator SomeFormValidator; [SetUp] public void Setup() { SomeFormValidator = new SomeFormValidator(); } [Test] public void Should_display_correct_error_message_MyClass_is_null() { //arrange MyClass myClass = null; //act var result = SomeFormValidator.ShouldHaveValidationErrorFor(x => x.MyClass, myClass); //assert result.WithErrorMessage("MyClass is required"); //first attempt prior to finding WithErrorMessage exists //foreach (var r in result) //{ // Assert.AreEqual("MyClass is required", r.ErrorMessage); //} } } 片段就是这种情况:求解器可能会放弃,但它所采用的启发式方法可能会解决实际问题。

对Rationals的限制

从理论上讲,事实证明,如果你只限于理性(而不是实际的实数),那么你确实可以编写一个一阶公式来识别整数。然而,编码不适合胆小的人:http://math.mit.edu/~poonen/papers/ae.pdf。此外,由于编码涉及量词,因此SMT求解器很可能不会很好地处理基于此思想的公式。

[顺便说一下,我要感谢我的同事;这个问题是为了一次很棒的午餐时间对话!]