Я пытаюсь представить временные ограничения в SMT-LIB, чтобы проверить их выполнимость. Я ищу обратную связь по направлению, которое я принимаю. Я относительно новичок в SMT-LIB, и я очень ценю материалы.Представление временных ограничений в SMT-LIB
Ограничения, которые у меня есть, касаются времени и продолжительности событий. Например, рассмотрим следующие ограничения, приведенные на естественном языке:
Джон начал писать эссе в 13:03:41, и ему потребовалось 20 минут, чтобы закончить его.
После того, как он написал письмо, он проверил его электронные письма, которые заняли его более 40 минут.
После проверки его электронной почты он позвонил жене.
Он позвонил жене после 14:00:00.
Нетрудно видеть, что этот набор ограничений является довольно эффективным, и я пытаюсь вывести его с помощью решателя SMT.
Чтобы иметь какую-то больную инкапсуляцию для понятий времени и продолжительности, я определил новые виды, которые представляют их в массивах. Некоторые макросы были определены для работы в качестве конструкций:
(define-sort Time() (Array Int Int))
(define-fun new_time_ns ((hours Int) (minutes Int) (seconds Int) (nanos Int)) Time
(store (store (store (store ((as const (Array Int Int)) 0) 1 hours) 2 minutes) 3 seconds) 4 nanos)
)
(define-sort Duration() (Array Int Int))
(define-fun new_duration_ns ((seconds Int) (nanos Int)) Duration
(store (store ((as const (Array Int Int)) 0) 1 seconds) 2 nanos)
)
Геттерз определяются с помощью макросов и позволяют получить конкретные меры, например:
(define-fun getDurationSecond ((d Duration)) Int
(select d 1)
)
(define-fun getDurationNano ((d Duration)) Int
(select d 2)
)
Некоторые утилиты макросы были определены для времени и длительности арифметических и для выражения отношений. Например, с помощью некоторых вспомогательных макросов мы определяем isLongerThan, isShorterThan и isEqualDuration следующим образом:
(define-fun cmpInt ((i1 Int) (i2 Int)) Int
(ite (< i1 i2) -1 (ite(> i1 i2) 1 0))
)
(define-fun cmpDuration ((d1 Duration) (d2 Duration)) Int
(ite (= (cmpInt (getDurationSecond d1) (getDurationSecond d2)) 0)
(ite (= (cmpInt (getDurationNano d1) (getDurationNano d2)) 0)
0
(cmpInt (getDurationNano d1) (getDurationNano d2)))
(cmpInt (getDurationSecond d1) (getDurationSecond d2)))
)
(define-fun isLongerThan ((d1 Duration) (d2 Duration)) Bool
(> (cmpDuration d1 d2) 0)
)
(define-fun isShorterThan ((d1 Duration) (d2 Duration)) Bool
(< (cmpDuration d1 d2) 0)
)
(define-fun isEqualDuration ((d1 Duration) (d2 Duration)) Bool
(= (cmpDuration d1 d2) 0)
)
Остальные определения можно найти в this file.
Исходя из этого я могу выразить ограничения по набору утверждений:
(declare-const write_start Time)
(declare-const write_end Time)
(declare-const write_duration Duration)
(declare-const check_start Time)
(declare-const check_end Time)
(declare-const check_duration Duration)
(declare-const phone_start Time)
(assert (= write_start (new_time_ns 13 03 41 0))) ; the writing started at 13:03:41
(assert (= write_duration (new_duration 1200))) ; the writing took 20 min (1200 sec).
(assert (= write_end (plusDuration write_start write_duration)))
(assert (isAfter check_start write_end)) ; the check started after the writing
(assert (isLongerThan check_duration (new_duration 2400))) ; the check took more than 40 min
(assert (= check_end (plusDuration check_start check_duration)))
(assert (isAfter phone_start check_end)) ; he phoned after the check
(assert (isAfter phone_start (new_time_ns 14 00 00 0))) ; it was after 14:00:00
(check-sat)
Некоторые вопросы и проблемы:
Дизайн-мудрый, мне было бы интересно узнать, является ли это является разумным моделированием проблемы в SMT-LIB.
Некоторые примечания для добавления здесь: (A) Я решил использовать массивы для представления объектов времени и продолжительности, поскольку они помогают группировать внутренние поля этих понятий (часы, минуты, секунды, нано). Можно также использовать отдельные целые числа. (B) Я полагаюсь на макросы (define-fun ...) очень сильно, и это может сделать ограничения немного сложными, но я не знаю, что еще можно было бы использовать для достижения требуемого уровня выразительности и ясности что текущий код имеет. (C) В настоящее время нет ограничений, ограничивающих поля времени, поэтому значение поля минут, например, может быть 78.Следует добавить утверждения, которые ограничивают секунды до 59, минут до 59 и часов до 23, но я не нашел элегантный способ сделать это.
Я предполагаю, что у меня есть разрешимый фрагмент FOL - QF_LIA - поскольку все ограничения объявляются с использованием линейных функций над целыми константами. Тем не менее, я попытался запустить the attached code через Z3 и даже после 40 минут работы локально на среднем компьютере он по-прежнему не возвращается с разрешением (sat/unsat). На самом деле я не знаю, может ли он решить проблему вообще. Возможно, мое предположение о том, что я в QF-LIA ошибается, и также возможно, что Z3 борется с этим типом ограничений. Я могу добавить, что, когда я пробовал более простые ограничения, Z3 удалось достичь разрешения, но я заметил, что созданные ими модели были очень сложными с большим количеством внутренних структур. Может кто-нибудь, пожалуйста, дайте мне некоторые идеи, чтобы исследовать здесь? Онлайн-прокси Z3 с моим кодом можно найти here. Я еще не пробовал других решателей SMT.
Я не знаю о параллельных работах, которые пытаются определить временные ограничения этого типа в SMT-LIB. Я действительно ценю ссылки на существующие работы.
Спасибо!
Если вы уже знакомы с CLTL (Constraint линейной темпоральной логики) и уметь моделировать вашу проблему в CLTL, вы можете используйте Zot и мой плагин ae2bvzot. https://github.com/fm-polimi/zot Он автоматически переводит формулу CLTL в smt2, запускает Z3 и отображает результат с назначением для каждой переменной в каждый момент времени. – mmpourhashem
Вы можете ограничить Z3 конкретной логикой, например, с помощью '(set-logic QF_LIA)' Z3 будет жаловаться, если ваша проблема не подходит без кванторной линейной целочисленной арифметики. – iago
Если вы используете массивы, тогда '(set-logic QF_AUFLIA)'. Однако ваше использование массивов _may_ должно быть частью проблемы. Если вы можете написать уродливую проблему SMT без использования массивов, я уверен, что Z3 решит ее гораздо быстрее. Добавление большего количества теорий в вашу спецификацию может только ухудшить ситуацию, поэтому постарайтесь выразить свою проблему, используя только 'QF_LIA'. – iago