记录类型中的多个数组时,数组模型中的Z3额外条件(ite子句)

时间:2018-09-13 12:08:46

标签: arrays record z3 smt

当一条记录包含多个相同类型的命名数组时,我在z3中遇到了一些意外行为:

(declare-datatypes () ((Record_lengths (Record_lengths (array (Array Int Int))))))
(declare-datatypes () ((ROI (ROI (array (Array Int Int))))))
(declare-datatypes () ((Record (Record (lengths Record_lengths) (roi ROI)))))
(declare-fun rec () Record)
(assert (= (select (array (lengths rec)) 1) 0))
(get-model)

我期望会有一个解决方案,其中rec.lengths [1] = 0,所有其他都是默认值或随机值。但是lengths选择器总是有一个附加的ite子句:

(model 
  (define-fun rec () Record
    (Record (Record_lengths (_ as-array k!1)) (ROI (_ as-array k!0))))
  (define-fun k!0 ((x!0 Int)) Int
    (ite (= x!0 2) 4
      4))
  (define-fun k!1 ((x!0 Int)) Int
    (ite (= x!0 1) 0
    (ite (= x!0 2) 3 ;this is unexpected
      0)))
)

这些额外子句的数量似乎与记录中相同数组类型的数量有某种关系。 像本例一样:Record_lengthsROI具有相同的类型,如果我向ROI添加更多的Record类型,则额外子句的数量也会增加。

这里是示例的永久链接: https://rise4fun.com/Z3/geoo

1 个答案:

答案 0 :(得分:1)

SMT求解器不能保证生成的模型在任何意义上都是“最小”的。当然,只要它们生成的模型满足您的所有约束即可。

话虽如此,您可以将选项用于部分模型并获得“更小”的示例。我的引号要小一些,因为,这里又没有下限的概念。除其他因素外,求解器认为什么是模型的一部分以及可以跳过什么可能会有所不同,具体取决于启发式方法。您可以添加:

(set-option :model.partial true)

在脚本顶部查看会产生什么影响。