-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathk_decid.ml
137 lines (111 loc) · 5.32 KB
/
k_decid.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
(* ========================================================================= *)
(* Decision procedure for the provability logic K. *)
(* *)
(* (c) Copyright, Marco Maggesi, Cosimo Perini Brogi 2020-2022. *)
(* (c) Copyright, Antonella Bilotta, Marco Maggesi, *)
(* Cosimo Perini Brogi, Leonardo Quartini 2024. *)
(* ========================================================================= *)
(* ------------------------------------------------------------------------- *)
(* Lemmata. *)
(* ------------------------------------------------------------------------- *)
let K_COMPLETENESS_NUM =
let K_COMPLETENESS_THEOREM_NUM =
REWRITE_RULE[num_INFINITE]
(INST_TYPE [`:num`,`:A`] K_COMPLETENESS_THM_GEN) in
prove
(`!p. (!W R V w:num.
(!p w. w IN W /\
(!y. y IN W /\ R w y ==> holds (W,R) V p y)
==> holds (W,R) V (Box p) w) /\
(!Q p w. w IN W /\
(!y. y IN W /\ R w y ==> holds (W,R) V p y \/ Q)
==> holds (W,R) V (Box p) w \/ Q) /\
(!w w'. R w w'
==> !p. holds (W,R) V (Box p) w ==> holds (W,R) V p w') /\
(!p w. holds (W,R) V (Box p) w
==> !w'. R w w' ==> holds (W,R) V p w') /\
w IN W
==> holds (W,R) V p w)
==> [{} . {} |~ p]`,
GEN_TAC THEN REWRITE_TAC[IMP_IMP] THEN DISCH_TAC THEN
MATCH_MP_TAC K_COMPLETENESS_THEOREM_NUM THEN
REWRITE_TAC[valid; FORALL_PAIR_THM; holds_in] THEN
REPEAT GEN_TAC THEN INTRO_TAC "itf" THEN REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
[REWRITE_TAC[holds] THEN ASM_MESON_TAC[IN_K_FRAME]; ALL_TAC] THEN
CONJ_TAC THENL [REWRITE_TAC[holds] THEN ASM_MESON_TAC[IN_K_FRAME]; ALL_TAC] THEN
CONJ_TAC THENL [REWRITE_TAC[holds] THEN ASM_MESON_TAC[IN_K_FRAME]; ALL_TAC] THEN
REWRITE_TAC[holds] THEN ASM_MESON_TAC[IN_K_FRAME]);;
(* ------------------------------------------------------------------------- *)
(* The work horse of the tactic. *)
(* ------------------------------------------------------------------------- *)
module Rule_K = struct
(* Non-recursive building block tactics. *)
let GEN_BOX_RIGHT_TAC (kacc:thm_tactic) : tactic =
let ptac =
CONJ_TAC THENL
[FIRST_ASSUM MATCH_ACCEPT_TAC;
GEN_TAC THEN
DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC kacc)] in
let ttac th = (MATCH_MP_TAC th THEN ptac) in
USE_THEN "boxr1" ttac ORELSE USE_THEN "boxr2" ttac
let rec SATURATE_ACC_TCL:thm_tactical = fun ttac th ->
LABEL_TAC "acc" th THEN STEP_BOXL1_TCL ttac th
let SATURATE_ACC_TAC:thm_tactic = fun th g ->
(STEP_BOXL1_TCL HOLDS_TAC th THEN SATURATE_ACC_TCL HOLDS_TAC th) g
(* Recursive theorem-tacticals. *)
let BOX_RIGHT_TAC = GEN_BOX_RIGHT_TAC SATURATE_ACC_TAC
(* Main tactic. *)
let K_RIGHT_TAC : tactic =
CONV_TAC HOLDS_NNFC_UNFOLD_CONV THEN
PURE_ASM_REWRITE_TAC[AND_CLAUSES; OR_CLAUSES; NOT_CLAUSES] THEN
CONV_TAC CNF_CONV THEN
REPEAT CONJ_TAC THEN
TRY (NEG_RIGHT_TAC HOLDS_TAC)
let K_STEP_TAC : tactic =
(FIRST o map CHANGED_TAC)
[K_RIGHT_TAC;
SORT_BOX_TAC THEN BOX_RIGHT_TAC];;
let INNER_K_TAC : tactic = REPEAT K_STEP_TAC
end;;
(* ------------------------------------------------------------------------- *)
(* Generate a countermodel. *)
(* ------------------------------------------------------------------------- *)
let the_K_countermodel : term ref = ref `F`;;
let K_BUILD_COUNTERMODEL : tactic =
let drop_labels =
["trans"; "boxr1"; "boxr2"; "boxl1"; "boxl2"] in
let drop_assumption s = mem s drop_labels in
let filter_asl =
mapfilter (fun s,t -> if drop_assumption s then fail() else concl t ) in
fun asl,w ->
let l = filter_asl asl in
the_K_countermodel :=
end_itlist (curry mk_conj) (l @ map mk_neg (striplist dest_disj w));
failwith
"Contermodel stored in reference the_K_countermodel.";;
(* ------------------------------------------------------------------------- *)
(* Top-level invocation. *)
(* ------------------------------------------------------------------------- *)
let K_TAC : tactic =
REPEAT GEN_TAC THEN REPEAT (CONV_TAC let_CONV) THEN REPEAT GEN_TAC THEN
REWRITE_TAC[diam_DEF; dotbox_DEF] THEN MATCH_MP_TAC K_COMPLETENESS_NUM THEN
REPEAT GEN_TAC THEN INTRO_TAC "boxr1 boxr2 boxl1 boxl2 w" THEN
REPEAT GEN_TAC THEN
(* Rule_gl.INNER_K_TAC THEN *)
INNER_K_TAC THEN
K_BUILD_COUNTERMODEL;;
let K_RULE (tm:term) : thm =
prove(tm,K_TAC);;
(* ------------------------------------------------------------------------- *)
(* Examples. *)
(* ------------------------------------------------------------------------- *)
K_RULE `!a b. [{} . {} |~ Box (a && b) <-> Box a && Box b]`;;
K_RULE `!a b. [{} . {} |~ Box a || Box b --> Box (a || b)]`;;
g `!a. [{} . {} |~ Box a --> a]`;;
e (TRY K_TAC);;
!the_K_countermodel;;
g `!a b. [{} . {} |~ Box (a || b) --> Box a || Box b]`;;
e (TRY K_TAC);;
!the_K_countermodel;;