簡體   English   中英

在SMT-LIB中表示時間約束

[英]Representing temporal constraints in SMT-LIB

我試圖在SMT-LIB中表示時間約束,以檢查它們的可滿足性。 我正在尋找有關我正在采取的方向的反饋。 我對SMT-LIB比較陌生,我非常欣賞輸入。

我所擁有的約束是關於事件的時間和持續時間。 例如,考慮以自然語言給出的以下約束:

  1. 約翰在13:03:41開始寫一篇文章,花了20分鍾完成它。

  2. 寫完之后,他檢查了他的電子郵件,這花了他超過40分鍾。

  3. 檢查完他的電子郵件后,他打電話給他的妻子。

  4. 他在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)
)

使用宏定義getter並允許我們檢索特定度量,例如:

(define-fun getDurationSecond ((d Duration)) Int
  (select d 1)
)

(define-fun getDurationNano ((d Duration)) Int
  (select d 2)
)

一些實用程序宏被定義為時間和持續時間算術以及表達關系。 例如,使用一些輔助宏我們定義isLongerThanisShorterThanisEqualDuration ,如下所示:

(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)
)

其余定義可以在此文件中找到。

基於此,我可以通過一組斷言來表達約束:

(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)

一些問題和問題:

  1. 在設計方面,我有興​​趣知道這是否是SMT-LIB中問題的合理建模。

  2. 這里要添加一些注意事項:(A)我決定使用數組來表示時間和持續時間對象,因為它們有助於對這些概念的內部字段進行分組(小時,分鍾,秒,納米)。 也可以使用單個整數。 (B)我非常依賴宏(define-fun ...),這可能會使約束變得有點復雜,但我不知道還能用什么來達到所需的表達能力和清晰度當前代碼有。 (C)目前沒有限制時間字段的約束,因此例如,分鍾字段的值可以是78.應該添加斷言,將秒限制為59,將分鍾限制為59,將小時限制為23 ,但我沒有找到一種優雅的方式來做到這一點。

  3. 我假設我處於FOL的可判斷片段 - QF_LIA - 因為所有約束都是使用線性函數在整數常量上聲明的。 但是,我嘗試通過Z3運行附加代碼 ,即使在普通計算機本地運行40分鍾后,它仍然沒有以分辨率(sat /不滿)返回。 我實際上不知道它是否可以解決問題。 我在QF-LIA中的假設可能是錯誤的,並且Z3也可能在這種類型的約束下掙扎。 我可以補充一點,當我嘗試更簡單的約束時,Z3設法達到分辨率,但我注意到它生成的模型非常復雜,有很多內部結構。 有人可以給我一些想法來調查嗎? 我的代碼可以在這里找到Z3的在線證明。 我還沒有嘗試過其他的SMT求解器。

  4. 我不知道嘗試在SMT-LIB中定義此類型的時間約束的並行工作。 我非常感謝對現有作品的參考。

謝謝!

我喜歡你的方法,但我認為通過定義你自己的種類,尤其是使用數組理論,你的情況過於復雜。

而且,在數學上,整數理論比它們的真實對應物更難。 例如,如果npq是實數,則“ n = pq ,求解p ”是微不足道的,但如果它們是整數,則它是整數因子分解,這很難。 類似地, x n + y n = z n ,n> 2在實數中很容易求解,但在整數中,這是費馬的最后定理。 這些例子是非線性的,但是如果你認為用於解決QF_LRA的技術被教給中學和高中學生,我聲稱你在QF_LRA比QF_LIA更好。 無論如何,時間更接近實數而不是一堆整數。

根據我對SMT解算器的總體經驗,特別是Z3,你最好使用更簡單的理論。 它將允許Z3使用其最強大的內部解算器。 如果您使用更復雜的理論(如數組),您可能會得到一個驚人的結果,或者您可能會發現求解器超時並且您不知道為什么,就像您提出的解決方案一樣。

從軟件工程的角度來看,這並不是很好,但在數學上我推薦以下簡單的解決方案來解決您提出的問題,其中所有時間都表示為實數,就感興趣當天午夜以來的秒數而言:

; Output all real-valued numbers in decimal-format.
(set-option :pp.decimal true)

; Convenience function for converting hh:mm:ss formatted times to seconds since midnight.
(define-fun time_hms ((hour Real) (minute Real) (second Real)) Real
    (+ (+ (* 3600.0 hour) (* 60.0 minute)) second)
)

; Convenience function for converting durations in minutes to seconds.
(define-fun duration_m ((minute Real)) Real
    (* 60.0 minute)
)

; Variable declarations. Durations are in seconds. Times are in seconds since midnight.
(declare-fun write_start () Real)
(declare-fun write_end () Real)
(declare-fun write_duration () Real)
(declare-fun check_start () Real)
(declare-fun check_end () Real)
(declare-fun check_duration () Real)
(declare-fun phone_start () Real)

; Constraints.

; 1. John started writing an essay at 13:03:41, and it took him 20 min to complete it.
(assert (= write_start (time_hms 13 03 41)))
(assert (= write_duration (duration_m 20)))
(assert (= write_end (+ write_start write_duration)))

; 2. After writing, he checked his emails, which took him more than 40 min.
(assert (> check_start write_end))
(assert (> check_duration (duration_m 40)))
(assert (= check_end (+ check_start check_duration)))

; 3. After checking his emails, he phoned his wife.
(assert (> phone_start check_end))

; 4. He phoned his wife after 14:00:00.
(assert (> phone_start (time_hms 14 00 00)))

(check-sat)
(get-value (write_start write_duration write_end check_start check_end check_duration phone_start))
(exit)

Z3和CVC4都很快找到了解決方案:

sat
((write_start 47021.0)
 (write_duration 1200.0)
 (write_end 48221.0)
 (check_start 48222.0)
 (check_end 50623.0)
 (check_duration 2401.0)
 (phone_start 50624.0))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM