Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

verify コマンドを追加 #52

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Conversation

cedretaber
Copy link
Collaborator

@cedretaber cedretaber commented Oct 26, 2024

概要

https://hackmd.io/xQoyRGzyRHGPFEK9XU70Ew

lean/z3 を使って validation を行う verify コマンドを追加。

src/ast2theorem.ml は dangtv/BIRDS から持ってきました。
中身を整えるのは別の PR でやりたいです。

動作確認

lean/z3 の環境が必要です。
lean は 3.4.2 、 z3 は 4.8.7 のバージョンで動作確認をしています。

以下の Docker Image を利用すると簡単に環境を作ることができます。
https://github.com/proof-ninja/docker-verify-BIRDS

成功

source tracks2('TRACK':string,'RATING':int,'ALBUM':string,'QUANTITY':int).
view tracks3('TRACK':string,'RATING':int,'ALBUM':string,'QUANTITY':int).
% view definition:
tracks3(T,R,A,Q) :- tracks2(T,R,A,Q),Q > 2.
% putdelta
+tracks2(T,R,A,Q) :- tracks3(T,R,A,Q), not tracks2(T,R,A,Q).
-tracks2(T,R,A,Q) :- tracks2(T,R,A,Q), not tracks3(T,R,A,Q), Q > 2.
% constraints
_|_ :- tracks3(T,R,A,Q), Q <= 2.
$ dune exec verify examples/verify_valid1.dl

...

>>> verified by lean: correct
The program satisfies all delta disjointness, getput and putget

失敗

source tracks2('TRACK':string,'RATING':int,'ALBUM':string,'QUANTITY':int).
view tracks3('TRACK':string,'RATING':int,'ALBUM':string,'QUANTITY':int).
% view definition:
tracks3(T,R,A,Q) :- tracks2(T,R,A,Q),Q > 2.
% putdelta
+tracks2(T,R,A,Q) :- tracks3(T,R,A,Q), not tracks2(T,R,A,Q).
-tracks2(T,R,A,Q) :- tracks2(T,R,A,Q), not tracks3(T,R,A,Q).
% constraints
_|_ :- tracks3(T,R,A,Q), Q <= 2.
$ dune exec verify examples/verify_invalid_getput1.dl

...

>>> verified by lean: correct
Fatal error: exception Birds.Utils.ChkErr("\n\nInvalidity: Property getput is not validated \nExit code: 1\nError messange: /tmp/b8bad8.lean:7:4: error: z3 was unable to prove the goal\nstate:\ntracks2 : string \226\134\146 \226\132\164 \226\134\146 string \226\134\146 \226\132\164 \226\134\146 Prop\n\226\138\162 (\226\136\128 (x : string) (x_1 : \226\132\164) (x_2 : string) (x_3 : \226\132\164),\n       (\194\172tracks2 x x_1 x_2 x_3 \226\136\168 tracks2 x x_1 x_2 x_3 \226\136\167 x_3 > 2) \226\136\168 \194\172tracks2 x x_1 x_2 x_3) \226\136\167\n    \226\136\128 (x : string) (x_1 : \226\132\164) (x_2 : string) (x_3 : \226\132\164),\n      ((\194\172tracks2 x x_1 x_2 x_3 \226\136\168 \194\172x_3 > 2) \226\136\168 tracks2 x x_1 x_2 x_3) \226\136\168 tracks2 x x_1 x_2 x_3\nHint: use option --counterexample to generate a counterexample")

@cedretaber cedretaber self-assigned this Oct 26, 2024
bin/verify.ml Outdated Show resolved Hide resolved
src/verify.ml Outdated
else
(* if (!cex_generation) then (print_endline !counterexample_mess; exit 0)
else *)
raise (Utils.ChkErr !verification_mess)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

例外投げるのではなく、普通に出力して終了しても良いかもしれない。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

元のコードからなのかもしれないけれど
>>> verified by lean: correct
は変わらないのだろうか 🤔
correctではなさそう

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確かに correct ではないですね 😇

コマンドライン引数の hint とか、現状と明らかに合ってない出力とかも今はそのままにしているので、動作確認してもらって良さそうなら直します 🙏

@cedretaber
Copy link
Collaborator Author

verify.ml のコードは古い main.ml から切り取ってきて少し手直ししたものだけど、書き方を全体的に修正しても良いかもしれない。

  • ref を使わずに結果とエラー表示とを取得するようにする
  • 深くネストした if をどうにかする
  • エラー内容を文字列で作るのではなく型で表現するなどして、表示用の出力は別のロジックとする
  • 適宜コードを関数に分割する

動作確認をして良さそうなら上のような修正を入れても良いと思う。

@cedretaber
Copy link
Collaborator Author

実際に処理されている Lean コードの例

examples/verify_valid1.dl から生成されたもの。

import bx

local attribute [instance] classical.prop_decidable

theorem disjoint_deltas {tracks2: (string → (int → (string → (int → Prop))))} {tracks3: (string → (int → (string → (int → Prop))))}: (((∃A, (∃Q, (∃R, (∃T, ((tracks3 T R A Q) ∧ (¬ (Q > (2: int)))))))) → false) → ((∃COL0, (∃COL1, (∃COL2, (∃COL3, (((tracks3 COL0 COL1 COL2 COL3) ∧ (¬ (tracks2 COL0 COL1 COL2 COL3))) ∧ (((tracks2 COL0 COL1 COL2 COL3) ∧ (¬ (tracks3 COL0 COL1 COL2 COL3))) ∧ (COL3 > (2: int)))))))) → false)):=
    begin
    z3_smt
    end
import bx

local attribute [instance] classical.prop_decidable

theorem getput {tracks2: (string → (int → (string → (int → Prop))))}: (true → (((∃COL0, (∃COL1, (∃COL2, (∃COL3, ((((tracks2 COL0 COL1 COL2 COL3) ∧ (¬ ((tracks2 COL0 COL1 COL2 COL3) ∧ (COL3 > (2: int))))) ∧ (COL3 > (2: int))) ∧ (tracks2 COL0 COL1 COL2 COL3)))))) ∨ (∃COL0, (∃COL1, (∃COL2, (∃COL3, ((((tracks2 COL0 COL1 COL2 COL3) ∧ (COL3 > (2: int))) ∧ (¬ (tracks2 COL0 COL1 COL2 COL3))) ∧ (¬ (tracks2 COL0 COL1 COL2 COL3)))))))) → false)):=
    begin
    z3_smt
    end
import bx

local attribute [instance] classical.prop_decidable

theorem putget {tracks2: (string → (int → (string → (int → Prop))))} {tracks3: (string → (int → (string → (int → Prop))))}: (((∃A, (∃Q, (∃R, (∃T, ((tracks3 T R A Q) ∧ (¬ (Q > (2: int)))))))) → false) → (∀ALBUM, (∀QUANTITY, (∀RATING, (∀TRACK, (((((tracks2 TRACK RATING ALBUM QUANTITY) ∧ (¬ (((tracks2 TRACK RATING ALBUM QUANTITY) ∧ (¬ (tracks3 TRACK RATING ALBUM QUANTITY))) ∧ (QUANTITY > (2: int))))) ∨ ((tracks3 TRACK RATING ALBUM QUANTITY) ∧ (¬ (tracks2 TRACK RATING ALBUM QUANTITY)))) ∧ (QUANTITY > (2: int))) ↔ (tracks3 TRACK RATING ALBUM QUANTITY))))))):=
    begin
    z3_smt
    end

examples/verify_invalid_getput1.dl から生成されているもの。

import bx

local attribute [instance] classical.prop_decidable

theorem disjoint_deltas {tracks2: (string → (int → (string → (int → Prop))))} {tracks3: (string → (int → (string → (int → Prop))))}: (((∃A, (∃Q, (∃R, (∃T, ((tracks3 T R A Q) ∧ (¬ (Q > (2: int)))))))) → false) → ((∃COL0, (∃COL1, (∃COL2, (∃COL3, (((tracks3 COL0 COL1 COL2 COL3) ∧ (¬ (tracks2 COL0 COL1 COL2 COL3))) ∧ ((tracks2 COL0 COL1 COL2 COL3) ∧ (¬ (tracks3 COL0 COL1 COL2 COL3)))))))) → false)):=
    begin
    z3_smt
    end
import bx

local attribute [instance] classical.prop_decidable

theorem getput {tracks2: (string → (int → (string → (int → Prop))))}: (true → (((∃COL0, (∃COL1, (∃COL2, (∃COL3, (((tracks2 COL0 COL1 COL2 COL3) ∧ (¬ ((tracks2 COL0 COL1 COL2 COL3) ∧ (COL3 > (2: int))))) ∧ (tracks2 COL0 COL1 COL2 COL3)))))) ∨ (∃COL0, (∃COL1, (∃COL2, (∃COL3, ((((tracks2 COL0 COL1 COL2 COL3) ∧ (COL3 > (2: int))) ∧ (¬ (tracks2 COL0 COL1 COL2 COL3))) ∧ (¬ (tracks2 COL0 COL1 COL2 COL3)))))))) → false)):=
    begin
    z3_smt
    end
import bx

local attribute [instance] classical.prop_decidable

theorem putget {tracks2: (string → (int → (string → (int → Prop))))} {tracks3: (string → (int → (string → (int → Prop))))}: (((∃A, (∃Q, (∃R, (∃T, ((tracks3 T R A Q) ∧ (¬ (Q > (2: int)))))))) → false) → (∀ALBUM, (∀QUANTITY, (∀RATING, (∀TRACK, (((((tracks2 TRACK RATING ALBUM QUANTITY) ∧ (¬ ((tracks2 TRACK RATING ALBUM QUANTITY) ∧ (¬ (tracks3 TRACK RATING ALBUM QUANTITY))))) ∨ ((tracks3 TRACK RATING ALBUM QUANTITY) ∧ (¬ (tracks2 TRACK RATING ALBUM QUANTITY)))) ∧ (QUANTITY > (2: int))) ↔ (tracks3 TRACK RATING ALBUM QUANTITY))))))):=
    begin
    z3_smt
    end


(*
(* take a view update datalog program and generate the theorem of checking whether all delta relations are disjoint *)
let lean_theorem_of_disjoint_delta (debug:bool) prog =

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここコメントアウトされているのはなぜだろうか?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ast2theoremはファイル丸ごとコピーしてるからここをいじるのは別プルリクかも

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そうですね、このファイルはそのまま持ってきただけです。
コマンドの動作確認が取れたら直していくのが良いかなと考えています。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR の概要にその旨記載しました。


(*
(* (unnecessary now see sourcestability_sentence_of_stt in ast2fol.ml) take a view update datalog program and generate SourceStability constraint (put s v = s) for its view update strategy *)
let sourcestability_of_stt (debug:bool) prog =

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここもコメントアウトか

@hiroshi-cl
Copy link

動作確認をして良さそうなら上のような修正を入れても良いと思う。

次のプルリクで良さそう

@yoshihiro503
Copy link
Member

@cedretaber
timeoutが指定できたいとのことです。
--timeout みたいなオプションでtimeoutの値が指定できるようにできますでしょうか?

@cedretaber
Copy link
Collaborator Author

--timeout オプションを追加しました。

--timeout オプションの使い方

--timeout に続けて timeout の 秒数 を渡してください。

$ dune exec verify -- examples/verify_test1.dl --timeout 30

従来通りオプション無しでも利用できます。この場合、 timeout はデフォルトの180秒になります。

注意点

上記の通り、 dune exec verify の後に -- を入れてからファイル名、 timeout などの引数を渡してください。
この -- を忘れると、 dune コマンドに対するオプションと見做されエラーとなります。

@cedretaber
Copy link
Collaborator Author

📝
オプションを取るコマンドが増えてきたので、コマンドラインオプション用のライブラリを導入して整理した方が良いかも。

@hiroyukikato
Copy link
Collaborator

Thanks! LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants