Для проблем без квантификатора Z3 (3.2) выберет для else
значение, которое чаще всего встречается в range
. Под range
здесь я подразумеваю конечный набор значений, которые Z3 присвоил конкретному конечному набору входных значений. В нашем примере только true
встречается в range
. Таким образом, true
выбрано в качестве значения else
.
Для задач без квантификаторов (и без массивов), если опция :model-compact true
не используется, то значение else
не имеет значения.
То есть, если формула F
выполнима, Z3 создаст модель M
. Затем, если мы изменим значение любого else
в M
, результирующая модель M’
все еще будет моделью для F
.
Таким образом, вы можете игнорировать else
или предполагать, что это то, что вы хотите, ЕСЛИ входная формула F
не содержит квантификаторов, F
не использует теорию массивов и :model-compact true
не используется.
Это свойство основано на алгоритмах, реализованных в настоящее время в Z3, и это может измениться в будущем.
Напротив, решение, предоставляемое MHS, не зависит от изменений в реализации Z3. В своем кодировании любой решатель SMT (который успешно создает модель) должен будет использовать false
в качестве значения функции в каждой точке, не указанной в антецеденте квантификатора.
Другой вариант - использовать оператор default
и кодировать вашу проблему с помощью массивов.
Когда используется оператор default
, мы должны рассматривать массивы как пары: (Actual Array, Default value).
Это значение по умолчанию используется для предоставления значения else
во время построения модели.
Z3 также имеет несколько встроенных аксиом для распространения значений по умолчанию на: store
и map
операторы.
Вот ваша проблема, закодированная с использованием этого подхода:
(set-option :produce-models true)
(declare-const FPolicy (Array Int Int Int Bool))
(assert (select FPolicy 0 1 30))
(assert (select FPolicy 0 2 20))
(assert (not (default FPolicy)))
(check-sat)
(get-model)