Skip to content

Commit ac69889

Browse files
committed
introducing maximum and minimum
1 parent 54db15c commit ac69889

File tree

4 files changed

+76
-43
lines changed

4 files changed

+76
-43
lines changed

Prover/Core.fs

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ open Microsoft.Z3
1818
// 2: ∧ ∨
1919
// 3: ¬
2020
// 4: = ≠ > < ≤ ≥
21-
// 5: + - × ÷
21+
// 5: + - × ÷ ↑ ↓
2222
// 6: - (unary minus) # :: ++ ◁ ▷
2323
// 7: variables, function applications, and other atoms like true, false, ϵ, expressions inside parenthesis and angle brackets, like universal and existential quantifiers
2424
// 8: array access
@@ -175,22 +175,24 @@ and Integer =
175175
member this.ToSymbolTree() =
176176
let toTree (e: WExpr) = e.ToSymbolTree()
177177

178-
let binary5 symbol x y =
179-
SymbolTree.Node(Symbol.Op(symbol, 5), [ toTree x; toTree y ])
178+
let binary b symbol x y =
179+
SymbolTree.Node(Symbol.Op(symbol, b), [ toTree x; toTree y ])
180+
181+
let binary5, binary4 = binary 5, binary 4
180182

181183
match this with
182184
| ExtInteger e -> e.ToSymbolTree()
183185
| Integer i -> SymbolTree.Node(Symbol.Const $"{i}", [])
184186
| UnaryMinus n -> SymbolTree.Node(Symbol.Op("-", 6), [ toTree n ])
187+
| Exceeds(x, y) -> binary4 ">" x y
188+
| LessThan(x, y) -> binary4 "<" x y
189+
| AtLeast(x, y) -> binary4 "" x y
190+
| AtMost(x, y) -> binary4 "" x y
191+
| IsDivisor(x, y) -> binary4 "" x y
185192
| Plus(x, y) -> binary5 "+" x y
186193
| Minus(x, y) -> binary5 "-" x y
187194
| Times(x, y) -> binary5 "×" x y
188195
| Divide(x, y) -> binary5 "÷" x y
189-
| Exceeds(x, y) -> binary5 ">" x y
190-
| LessThan(x, y) -> binary5 "<" x y
191-
| AtLeast(x, y) -> binary5 "" x y
192-
| AtMost(x, y) -> binary5 "" x y
193-
| IsDivisor(x, y) -> binary5 "" x y
194196
| Max(x, y) -> binary5 "" x y
195197
| Min(x, y) -> binary5 "" x y
196198

@@ -219,24 +221,16 @@ and Integer =
219221
let p, q = toExp n, toExp m
220222
ctx.MkLe(p, q)
221223
| IsDivisor(n, m) ->
222-
// exists x such n*x = m
223-
let extractVar =
224-
function
225-
| ExtInteger a ->
226-
match a with
227-
| :? Var as z -> Some z.Name
228-
| _ -> None
229-
| _ -> None
230-
231-
let varSet = [ n; m ] |> List.choose extractVar |> Set
232-
let x = varSet - Set [ "x"; "y"; "z" ] |> Set.toList |> List.head
233-
// x ∉ { n, m }
234-
235-
let x = ctx.MkIntConst x
224+
// ⟨∃x :: n*x = m⟩
225+
let x = ctx.MkBound(0u, ctx.IntSort) :?> ArithExpr
236226
let p, q = toExp n, toExp m
237227
ctx.MkExists([| x |], ctx.MkEq(ctx.MkMul(p, x), q))
238-
| Max(_, _) -> failwith "Not Implemented"
239-
| Min(_, _) -> failwith "Not Implemented"
228+
| Min(n, m) ->
229+
let n, m = toExp n, toExp m
230+
ctx.MkITE(ctx.MkLe(n, m), n, m)
231+
| Max(n, m) ->
232+
let n, m = toExp n, toExp m
233+
ctx.MkITE(ctx.MkGe(n, m), n, m)
240234

241235
member this.TextualSubstitution (varName: string) (expr: WExpr) : WExpr =
242236
let substitute (e: WExpr) =
@@ -260,8 +254,8 @@ and Integer =
260254
| AtLeast(left, right) -> AtLeast(substitute left, substitute right)
261255
| AtMost(left, right) -> AtMost(substitute left, substitute right)
262256
| IsDivisor(left, right) -> IsDivisor(substitute left, substitute right)
263-
| Max(_, _) -> failwith "Not Implemented"
264-
| Min(_, _) -> failwith "Not Implemented"
257+
| Max(left, right) -> Max(substitute left, substitute right)
258+
| Min(left, right) -> Min(substitute left, substitute right)
265259

266260
and QuantifierDef =
267261
| Forall
@@ -272,20 +266,24 @@ and QuantifierDef =
272266
| Sum
273267

274268
and Quantifier =
275-
| Quantifier of QuantifierDef * vars: WExpr list * body: WExpr
269+
| Quantifier of QuantifierDef * vars: WExpr list * range: Proposition * body: WExpr
276270

277271
member this.Body =
278-
let (Quantifier(_, _, body)) = this
272+
let (Quantifier(_, _, _, body)) = this
279273
body
280274

281275
member this.Vars =
282-
let (Quantifier(_, vars, _)) = this
276+
let (Quantifier(_, vars, _, _)) = this
283277
vars
284278

285279
member this.QuantifierDef =
286-
let (Quantifier(q, _, _)) = this
280+
let (Quantifier(q, _, _, _)) = this
287281
q
288282

283+
member this.Range =
284+
let (Quantifier(_, _, range, _)) = this
285+
range
286+
289287
interface WExpr with
290288
member this.ToSymbolTree() : SymbolTree =
291289
let symbol =
@@ -334,13 +332,20 @@ and Quantifier =
334332
match this.QuantifierDef with
335333
| Forall -> ctx.MkForall(z3Vars, body = z3Body, patterns = patterns)
336334
| Exists -> ctx.MkExists(z3Vars, body = z3Body, patterns = patterns)
337-
| Maximum -> failwith "transforming Maximum quantifiers requires an equality"
338-
| Minimum -> failwith "transforming Minimum quantifiers requires an equality"
335+
| Maximum ->
336+
// TODO recursive definition
337+
failwith $"not implemented {this}"
338+
| Minimum -> failwith $"not implemented {this}"
339339
| Product -> failwith "Not Implemented"
340340
| Sum -> failwith "Not Implemented"
341341

342342
member this.TextualSubstitution (arg: string) (arg_1: WExpr) : WExpr =
343-
raise (System.NotImplementedException())
343+
Quantifier(
344+
this.QuantifierDef,
345+
this.Vars,
346+
(this.Range :> WExpr).TextualSubstitution arg arg_1 :?> Proposition,
347+
this.Body.TextualSubstitution arg arg_1
348+
)
344349

345350
and Proposition =
346351
| ExtProposition of WExpr // used for wrapping other operators that return booleans besides Equals and Differs (variables, >, <, etc.)

Prover/GriesSchneider.fs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ let (<&&>) x y = And(toBinaryProposition "∧" x y)
5555
let (<||>) x y = Or(toBinaryProposition "" x y)
5656

5757
let ``∀`` vars f =
58-
ExtProposition(Quantifier(Forall, vars, f))
58+
ExtProposition(Quantifier(Forall, vars, True, f))
5959

6060
let ``∃`` vars f =
61-
ExtProposition(Quantifier(Exists, vars, f))
61+
ExtProposition(Quantifier(Exists, vars, True, f))
6262

6363
let axiom name (pred: Proposition) = Law(name, pred)
6464

@@ -272,11 +272,33 @@ let ``GS 15.35`` () =
272272
let monotonicity () =
273273
proof { lemma (n < m ==> (n + p < m + p)) }
274274

275-
let ``↑`` vars body =
276-
ExtInteger(Quantifier(Maximum, vars, body))
275+
let ``↓ symmetry`` () =
276+
proof { theorem "↓ symmetry" (Min(n, m) = Min(m, n)) }
277+
278+
let ``↑ symmetry`` () =
279+
proof { theorem "↑ symmetry" (Max(n, m) = Max(m, n)) }
280+
281+
let ``↓ associativity`` () =
282+
proof { theorem "↓ associativity" (Min(n, Min(m, p)) = Min(Min(n, m), p)) }
283+
284+
let ``↑ associativity`` () =
285+
proof { theorem "↑ associativity" (Max(n, Max(m, p)) = Max(Max(n, m), p)) }
286+
287+
let ``↑ idempotency`` () =
288+
proof { theorem "↑ idempotency" (Max(n, n) = n) }
289+
290+
let ``↓ idempotency`` () =
291+
proof { theorem "↓ idempotency" (Min(n, n) = n) }
292+
293+
let ``GS 15.58`` () =
294+
proof { theorem "GS 15.58" (n <= m === (Min(n, m) = n)) }
295+
296+
let ``+ over ↓`` () =
297+
proof { theorem "+ over ↓" (p + Min(n, m) = Min(p + n, p + m)) }
298+
299+
let ``+ over ↑`` () =
300+
proof { theorem "+ over ↑" (p + Max(n, m) = Max(p + n, p + m)) }
277301

278-
let ``↓`` vars body =
279-
ExtInteger(Quantifier(Minimum, vars, body))
280302

281303
// Sequences
282304

Prover/Inspect.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ let checkAll (xs: list<unit -> Core.CheckedCalculation>) =
190190
let failIfNotProved (x: Inspection) =
191191
match x.Calc.Error with
192192
| Some(Core.WrongEvidence(counterExample, p, c)) ->
193-
failwith $"Counter-example found {counterExample}: {p} doesn't imply {c}"
193+
failwith $"Counter-example found {counterExample}:\n laws {p} don't imply {c}"
194194
| Some e -> failwith $"{e}"
195195
| None -> ()
196196

Test/IntegersTest.fs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ let ``check integer theorems`` () =
1111
``GS 15.23``
1212
``GS 15.34``
1313
``GS 15.35``
14-
monotonicity ]
14+
monotonicity
15+
``↓ symmetry``
16+
``↑ symmetry``
17+
``↑ associativity``
18+
``↓ associativity``
19+
``↓ idempotency``
20+
``↑ idempotency``
21+
``GS 15.58``
22+
``+ over ↓`` ]
1523
|> Inspect.checkAll
1624

17-
18-
1925
[<Fact>]
2026
let ``integer string representation`` () =
2127
[ n + m, "n + m"

0 commit comments

Comments
 (0)