Skip to content

Commit 08e9588

Browse files
author
GBathie
committed
Add comments and introduce 'satisfies'
1 parent 4e079c2 commit 08e9588

5 files changed

Lines changed: 117 additions & 52 deletions

File tree

BoltLean/Basic.lean

Lines changed: 0 additions & 1 deletion
This file was deleted.

BoltLean/Boolean/Basic.lean

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,41 @@
1-
abbrev Valuation (n_var: Nat): Type := Vector Bool n_var
1+
/-- A valuation represents the membership of a given element `x` of the universe
2+
in each of the sets `S_1, ..., S_{n_sets}` of the instance.
3+
It is an alias for `Vector Bool n_sets`,
4+
and `v[i]` says whether `x` is in `S_i`.-/
5+
abbrev Valuation (n_sets: Nat): Type := Vector Bool n_sets
26

37
/- Boolean formulas in NNF -/
4-
inductive BoolFormula (n_var: Nat)
5-
| False: BoolFormula n_var
6-
| True : BoolFormula n_var
7-
| Var : Fin n_var -> (neg: Bool) -> BoolFormula n_var
8-
| And : BoolFormula n_var -> BoolFormula n_var -> BoolFormula n_var
9-
| Or : BoolFormula n_var -> BoolFormula n_var -> BoolFormula n_var
8+
inductive BoolFormula (n_sets: Nat)
9+
| False: BoolFormula n_sets
10+
| True : BoolFormula n_sets
11+
| Var : Fin n_sets -> (neg: Bool) -> BoolFormula n_sets
12+
| And : BoolFormula n_sets -> BoolFormula n_sets -> BoolFormula n_sets
13+
| Or : BoolFormula n_sets -> BoolFormula n_sets -> BoolFormula n_sets
1014
deriving DecidableEq, Repr
1115

1216
namespace BoolFormula
1317
@[simp]
14-
def accepts (f: BoolFormula n_var) (v: Valuation n_var): Prop :=
18+
def accepts (f: BoolFormula n_sets) (v: Valuation n_sets): Prop :=
1519
match f with
1620
| False => _root_.False
1721
| True => _root_.True
1822
| Var i neg => v[i] ^^ neg
1923
| And f1 f2 => f1.accepts v ∧ f2.accepts v
2024
| Or f1 f2 => f1.accepts v ∨ f2.accepts v
2125

22-
def dominates (f1 f2: BoolFormula n_var): Prop :=
23-
∀ (v: Valuation n_var), f2.accepts v → f1.accepts v
26+
/-- A formula satisfies an examples if it is positive and the formula accepts,
27+
or if it is negative and the formula rejects.-/
28+
@[simp]
29+
def satisfies (f: BoolFormula n_sets) (v: Valuation n_sets) (positive: Bool) : Prop :=
30+
f.accepts v ↔ positive
31+
32+
/-- A formula `f1` dominates `f2` another if `f1` satisfies a superset
33+
of the elements satisfied by `f2`.-/
34+
def dominates (f1 f2: BoolFormula n_sets): Prop :=
35+
∀ (v: Valuation n_sets) (b: Bool), f2.satisfies v b → f1.satisfies v b
2436

25-
def replace (f pat repl: BoolFormula n_var): BoolFormula n_var :=
37+
/-- Replace all occurrence of the formula `pat` in `f` with the formula `repl`.-/
38+
def replace (f pat repl: BoolFormula n_sets): BoolFormula n_sets :=
2639
if f = pat then
2740
repl
2841
else match f with

BoltLean/Boolean/Domination.lean

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
11
import BoltLean.Boolean.Basic
22

33
namespace BoolFormula
4-
theorem true_replace_accepts (f1 f2: BoolFormula n_var):
5-
f1.dominates f2 -> ∀ (v: Valuation n_var), (True.replace f2 f1).accepts v := by
4+
/-- Aux Lemma: `True` -/
5+
theorem true_replace_accepts (f1 f2: BoolFormula n):
6+
f1.dominates f2 -> ∀ (v: Valuation n), (True.replace f2 f1).accepts v := by
67
intro h v
78
simp [replace]
89
split
910
. next heq =>
1011
rw [←heq] at h
12+
simp [dominates] at h
1113
apply h
12-
simp
1314
. next hne => simp
1415

16+
/-- Aux Lemma: `False` -/
17+
theorem false_replace_not_accepts (f1 f2: BoolFormula n):
18+
f1.dominates f2 -> ∀ (v: Valuation n), ¬ (False.replace f2 f1).accepts v := by
19+
intro h v
20+
simp [replace]
21+
split
22+
. next heq =>
23+
rw [←heq] at h
24+
simp [dominates] at h
25+
apply h
26+
. next hne => simp
1527

16-
theorem var_replace_accepts (f1 f2: BoolFormula n_var) (i: Fin n_var) (neg: Bool):
17-
f1.dominates f2 -> ∀ (v: Valuation n_var), (Var i neg).accepts v -> ((Var i neg).replace f2 f1).accepts v := by
18-
intro h v hv
28+
/-- Aux Lemma: `Var` -/
29+
theorem var_replace_accepts (f1 f2: BoolFormula n) (i: Fin n) (neg: Bool):
30+
f1.dominates f2 ->
31+
∀ (v: Valuation n) (b: Bool),
32+
(Var i neg).satisfies v b -> ((Var i neg).replace f2 f1).satisfies v b := by
33+
intro h v b hv
1934
simp [replace]
2035
split
2136
. next heq =>
@@ -24,41 +39,59 @@ namespace BoolFormula
2439
exact hv
2540
. next hne => assumption
2641

27-
theorem domin_replace (f1 f2: BoolFormula n_var):
42+
/-- Theorem: if f1 dominates f2, then in any formula f,
43+
replacing f2 by f1 yields a dominating formula.-/
44+
theorem domin_replace (f1 f2: BoolFormula n):
2845
f1.dominates f2 →
29-
∀ (f: BoolFormula n_var), (f.replace f2 f1).dominates f := by
30-
intro hd f v ha
46+
∀ (f: BoolFormula n), (f.replace f2 f1).dominates f := by
47+
intro hd f v b ha
3148
induction f with
32-
| True => exact true_replace_accepts f1 f2 hd v
33-
| False => contradiction
49+
| True =>
50+
cases b with
51+
| false => simp at ha
52+
| true => simp; exact true_replace_accepts f1 f2 hd v
53+
| False =>
54+
cases b with
55+
| false => simp [replace]; exact false_replace_not_accepts f1 f2 hd v
56+
| true => simp at ha
3457
| Var i neg =>
3558
apply var_replace_accepts
3659
<;> assumption
3760
| And g1 g2 ih1 ih2 =>
3861
simp [replace]
3962
split
4063
. next heq =>
41-
rw [←heq] at hd
42-
apply hd v
43-
assumption
64+
apply hd
65+
rw [heq] at ha
66+
exact ha
4467
. next hne =>
45-
simp
46-
simp at ha
47-
constructor
48-
. exact ih1 ha.left
49-
. exact ih2 ha.right
68+
cases b with
69+
| false =>
70+
simp at *
71+
intro h
72+
by_cases hx: g1.accepts v
73+
. exact ih2 (ha hx)
74+
. have hc:= ih1 hx
75+
contradiction
76+
| true =>
77+
simp at *
78+
exact ⟨ih1 ha.left, ih2 ha.right⟩
5079
| Or g1 g2 ih1 ih2 =>
5180
simp [replace]
5281
split
5382
. next heq =>
54-
rw [←heq] at hd
55-
apply hd v
83+
apply hd
84+
rw [heq] at ha
5685
assumption
5786
. next hne =>
58-
simp
59-
simp at ha
60-
match ha with
61-
| .inl h1 => left; exact ih1 h1
62-
| .inr h2 => right; exact ih2 h2
87+
cases b with
88+
| false =>
89+
simp at *
90+
exact ⟨ih1 ha.left, ih2 ha.right⟩
91+
| true =>
92+
simp at *
93+
match ha with
94+
| .inl h1 => left; exact ih1 h1
95+
| .inr h2 => right; exact ih2 h2
6396

6497
end BoolFormula

BoltLean/Ltl/Basic.lean

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
/-- `Trace n_pred` is an alias for `List (Vector Bool n_pred)`.
2+
At position `i` in the list, the vector contains the truth value of the `n_pred` predicates at time `i`.-/
13
abbrev Trace (n_pred: Nat): Type := List (Vector Bool n_pred)
24

35
/-- LTL Formulas in NNF -/
46
inductive Formula n_pred
57
| True : Formula n_pred
68
| False : Formula n_pred
7-
| Var : Fin n_pred -> (neg: Bool) -> Formula n_pred -- neg: Whether the variable is negated
9+
/-- neg: Whether the variable is negated -- negations are only allowed at variables. -/
10+
| Var : Fin n_pred -> (neg: Bool) -> Formula n_pred
811
| Next : Formula n_pred -> Formula n_pred
912
| WeakNext : Formula n_pred -> Formula n_pred
1013
| Globally : Formula n_pred -> Formula n_pred
@@ -15,9 +18,11 @@ inductive Formula n_pred
1518
deriving DecidableEq
1619

1720
namespace Formula
18-
21+
/-- Whether the formula is satisfied by the Trace.-/
1922
def accepts (phi: Formula n) (t: Trace n): Prop :=
2023
match t with
24+
-- Special case of the empty Trace: it is only accepted by True and Globally,
25+
-- or their boolean combinations.
2126
| .nil => match phi with
2227
| True | Globally _ => _root_.True
2328
| False | Finally _ | Var _ _ | Next _ | WeakNext _ | Until _ _ => _root_.False
@@ -37,6 +42,4 @@ namespace Formula
3742
(accepts psi2 (t.drop j)) ∧
3843
(∀ k, k < j → accepts psi1 (t.drop k))
3944

40-
def equivalence (phi psi : Formula n) : Prop := ∀ (t : Trace n), accepts phi t ↔ accepts psi t
41-
4245
end Formula

BoltLean/Ltl/UpperBound.lean

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
import BoltLean.Ltl.Basic
22

33
namespace Trace
4+
/-- Returns a formula that accepts the value of predicate number `v`,
5+
at the given position,
6+
i.e. it returns the variable x_v if x_v is true,
7+
and ¬x_v otherwise. -/
48
def get_exact_var (pos: Vector Bool n) (v: Fin n): Formula n :=
59
Formula.Var v (not pos[v])
610

7-
/-- Auxiliary function for constructing a formula that is true on t and only on t-/
11+
/-- Construct a formula that accepts the value of all predicates listed in `l`
12+
at the given position.
13+
To build the `exact` function, this function is called with `List.finRange n`,
14+
but having `l` as a free parameter makes proofs easier.-/
815
def exact_at_pos (pos: Vector Bool n) (l: List (Fin n)): Formula n :=
916
let all_var := l.map (get_exact_var pos)
10-
all_var.foldr (fun phi psi => phi.And psi) Formula.True
17+
all_var.foldr Formula.And Formula.True
1118

19+
/-- Return a formula that accepts `t` and rejects all other traces.-/
1220
def exact (t: Trace n) : Formula n :=
1321
match t with
1422
| .nil => Formula.False.Globally
@@ -41,9 +49,8 @@ namespace Trace
4149
. exact ih
4250

4351
-- Soundness
44-
/-- Taking the `And` of a list of formulas and evaluating is the same as
45-
evaluating and taking the `And`.
46-
-/
52+
/-- Lemma: Taking the `And` of a list of formulas and evaluating is the same as
53+
evaluating and taking the Boolean `And`.-/
4754
theorem foldr_and_aux (l: List (Formula n)) (t: Trace n):
4855
(l.foldr Formula.And Formula.True).accepts t
4956
→ ∀ f ∈ l, f.accepts t := by
@@ -62,6 +69,7 @@ namespace Trace
6269
simp [*] at he
6370
cases t <;> simp at he <;> apply ih he.right f h_in
6471

72+
/-- Lemma: If `exact_at_pos pos l` accepts, then `get_exact_var pos v` also accepts for all `v ∈ l`-/
6573
theorem exact_at_pos_accepts_all (pos pos': Vector Bool n) (t: Trace n) (l: List (Fin n)) :
6674
(exact_at_pos pos l).accepts (pos' :: t) → ∀ v ∈ l, (get_exact_var pos v).accepts (pos' :: t) := by
6775
intro h v hv
@@ -83,6 +91,7 @@ namespace Trace
8391
apply h1
8492
exact h2
8593

94+
/-- Lemma: If `exact t` accepts `t'`, then `t` and `t'` have the same head.-/
8695
theorem exact_accepts_head (h h': Vector Bool n) (t t': Trace n):
8796
(exact (h::t)).accepts (h'::t') → h = h' := by
8897
simp [exact, Formula.accepts]
@@ -93,6 +102,7 @@ namespace Trace
93102
simp [get_exact_var] at h1
94103
rw [h1]
95104

105+
/-- Lemma: If `exact t` accepts `t'`, then `t` and `t'` have the same tail.-/
96106
theorem exact_accepts_cons (h h': Vector Bool n) (t t': Trace n):
97107
(exact (h::t)).accepts (h'::t') → (exact t).accepts t' := by
98108
intro hyp
@@ -104,6 +114,7 @@ namespace Trace
104114
simp at h2
105115
exact h2
106116

117+
/-- Lemma: `exact` of the empty trace does not accept non-empty traces.-/
107118
theorem exact_nil_not_accepts_cons (h: Vector Bool n) (t: Trace n):
108119
¬ (exact []).accepts (h :: t) := by
109120
intro h1
@@ -139,7 +150,7 @@ namespace Trace
139150
assumption
140151

141152

142-
/-- Correctness of `t.exact` -/
153+
/-- Correctness and soundness of `t.exact` -/
143154
theorem exact_correct (t t': Trace n):
144155
t.exact.accepts t' ↔ t = t' := by
145156
constructor
@@ -162,12 +173,14 @@ namespace Trace
162173

163174
end Trace
164175

165-
176+
/-- Given a list of traces, construct a formula that accepts
177+
exactly these traces, and no other. -/
166178
def UpperBoundFormula (ts: List (Trace n)) : Formula n :=
167179
let fs := ts.map Trace.exact
168180
fs.foldr Formula.Or Formula.False
169181

170-
182+
/-- Lemma: If all formulas in a list accept `t`,
183+
then the `Or` of this list also accepts `t`.-/
171184
theorem foldr_or_aux (l: List (Formula n)) (t: Trace n):
172185
∀ f ∈ l, f.accepts t → (l.foldr Formula.Or Formula.False).accepts t := by
173186
induction l with
@@ -186,6 +199,9 @@ theorem foldr_or_aux (l: List (Formula n)) (t: Trace n):
186199
cases t <;> simp <;> right <;> apply ih f h_in he
187200

188201

202+
203+
/-- Lemma: If the `Or` of a list of formulas accepts `t`,
204+
then some formula in the list accepts `t`.-/
189205
theorem foldr_or_aux_rev (l: List (Formula n)) (t: Trace n):
190206
(l.foldr Formula.Or Formula.False).accepts t → ∃ f ∈ l, f.accepts t := by
191207
intro h
@@ -221,8 +237,9 @@ theorem list_map_contains (l: List α) (f: α → β):
221237
exact h2
222238

223239

224-
/-- Theorem X (TODO) from the paper:
225-
For any disjoint set of positive and negative examples, there exists a formula that accepts the positive rand rejects the negatives.
240+
/-- Theorem:
241+
For any disjoint set of positive and negative examples,
242+
there exists a formula that accepts all the positive and rejects the negatives.
226243
-/
227244
theorem UpperBound (pos: List (Trace n)) (neg: List (Trace n)) (h: ∀ t ∈ pos, ∀ t'∈ neg, t ≠ t') :
228245
exists (phi: Formula n), (∀ t ∈ pos, phi.accepts t) ∧ (∀t ∈ neg, ¬ phi.accepts t):= by

0 commit comments

Comments
 (0)