Skip to content

Commit 3a98281

Browse files
committed
Fix congruence issues (some statements where missing assumptions that were silently added).
1 parent 25119bf commit 3a98281

6 files changed

Lines changed: 46 additions & 83 deletions

File tree

lisa-sets/src/main/scala/lisa/Tests.scala

Lines changed: 0 additions & 68 deletions
This file was deleted.

lisa-sets/src/main/scala/lisa/automation/Congruence.scala

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,24 @@ object Congruence extends ProofTactic with ProofSequentTactic with ProofFactSequ
3030
val botWithAssumptions = bot.left ++ newAssumptions.map(_._1) |- bot.right
3131
var seq = botWithAssumptions
3232

33-
TacticSubproof {
33+
TacticSubproof { iProof ?=>
3434
import lib.*
3535

3636
have(botWithAssumptions) by this
37-
for ((assumption, f) <- newAssumptions.reverse) {
37+
//println(s"Bot with assumptions: $botWithAssumptions")
38+
for ((assumption, f) <- newAssumptions) {
39+
//println(s"eliminating premise ${f.statement}")
3840
val assumsOfPrem = f.statement.left
3941
if lastStep.statement.left.contains(assumption) then
40-
val seq = (lastStep.statement.left - assumption) ++ assumsOfPrem |- lastStep.statement.right
42+
val assumptionWeWantToGet = (lastStep.statement.left - assumption)
43+
val seq = assumptionWeWantToGet ++ assumsOfPrem |- lastStep.statement.right
4144
have(seq) by Cut(f, lastStep)
45+
//println(s"seq after cutting with the premise: $seq")
4246
assumsOfPrem.foldLeft(lastStep) { (step, a) =>
43-
if !bot.left.exists(botAssumption => isSame(a, botAssumption)) then
47+
if !assumptionWeWantToGet.exists(acceptableAssum => isSame(a, acceptableAssum)) then
48+
this((step.statement.left - a) |- a) match
49+
case r: iProof.ValidProofTactic => r.validate
50+
case iProof.InvalidProofTactic(e) => return proof.InvalidProofTactic(s"Failed to prove $a from ${step.statement.left - a} while eliminating premise ${f.statement}: $e")
4451
val aProof = have((step.statement.left - a) |- a) by this //TODO: catch errors
4552
have(step.statement -<< a) by Cut(aProof, step)
4653
else step

lisa-sets/src/main/scala/lisa/maths/SetTheory/Base/CartesianProduct.scala

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,25 @@ object CartesianProduct extends lisa.Main {
296296
)
297297
}
298298

299+
val R = variable[Ind]
300+
val CongTest = Theorem(
301+
(A × B) (C × D) R
302+
) {
303+
val left = have((A × B) R) by Sorry
304+
val right = have((C × D) R) by Sorry
305+
val s1 = Union.idempotence of (x := R)
306+
val s2 = Union.monotonic of (x := (A × B), y := (C × D), a := R, b := R)
307+
308+
have(s1.statement) by Restate.from(s1)
309+
have(s2.statement) by Restate.from(s2)
310+
311+
have(thesis) by Congruence.from(
312+
s1,
313+
s2,
314+
left,
315+
right
316+
)
317+
}
299318
/**
300319
* Theorem --- The union of two Cartesian products `A × B` and `C × D` is a subset
301320
* of the Cartesian product of the unions.
@@ -315,10 +334,15 @@ object CartesianProduct extends lisa.Main {
315334
Union.rightSubset of (x := A, y := C),
316335
Union.rightSubset of (x := B, y := D)
317336
)
337+
val s1 = Union.idempotence of (x := RHS)
338+
val s2 = Union.monotonic of (x := (A × B), y := (C × D), a := RHS, b := RHS)
339+
340+
have(s1.statement) by Restate.from(s1)
341+
have(s2.statement) by Restate.from(s2)
318342

319343
have(thesis) by Congruence.from(
320-
Union.monotonic of (x := (A × B), y := (C × D), a := RHS, b := RHS),
321-
Union.idempotence of (x := RHS),
344+
s1,
345+
s2,
322346
left,
323347
right
324348
)

lisa-sets/src/main/scala/lisa/maths/SetTheory/Functions/BasicTheorems.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,8 @@ object BasicTheorems extends lisa.Main {
344344

345345
// 6. g(fst(z)) = snd(z)
346346
val step6 = have(g(fst(z)) === snd(z)) by Congruence.from(
347-
step4,
348-
step5
347+
step5,
348+
step4
349349
)
350350

351351
// 7. fst(z) ∈ dom(g)

lisa-sets/src/main/scala/lisa/maths/SetTheory/Order/WellOrders/WellOrderedRecursion.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ object WellOrderedRecursion extends lisa.Main {
145145
}
146146

147147
// By definition of G1(x) and G2(x), this means that G1(x) === G2(x)
148-
have(minimal(x)(D)(<) |- G1(x) === G2(x)) by Congruence.from(
149-
lastStep,
148+
have((x A, minimal(x)(D)(<)) |- G1(x) === G2(x)) by Congruence.from(
150149
`G1(x)`,
151-
`G2(x)`
150+
`G2(x)`,
151+
lastStep
152152
)
153153

154154
// Contradiction since x ∈ D implies G1(x) ≠ G2(x)
@@ -349,7 +349,7 @@ object WellOrderedRecursion extends lisa.Main {
349349
}
350350

351351
// By definition of f(x) and g(x), this means that f(x) === g(x)
352-
have(minimal(x)(D)(<) |- f(x) === g(x)) by Congruence.from(
352+
have((x dom(f), x dom(g), minimal(x)(D)(<)) |- f(x) === g(x)) by Congruence.from(
353353
lastStep,
354354
`f(x)`,
355355
`g(x)`
@@ -739,7 +739,7 @@ object WellOrderedRecursion extends lisa.Main {
739739
thenHave(y initialSegment(x)(A)(<) |- dom(G_(y)) D) by Substitute(`d ∈ D` of (d := dom(G_(y))))
740740

741741
val `==>` = have((D) initialSegment(x)(A)(<)) subproof {
742-
have((y A, y < x, G_(y) === f, dom(f) === d) |- d initialSegment(x)(A)(<)) by Congruence.from(
742+
have((y initialSegment(x)(A)(<), y A, y < x, G_(y) === f, dom(f) === d) |- d initialSegment(x)(A)(<)) by Congruence.from(
743743
InitialSegment.monotonic of (x := y, y := x),
744744
`dom(G_y)`
745745
)
@@ -811,7 +811,7 @@ object WellOrderedRecursion extends lisa.Main {
811811
have(y initialSegment(x)(A)(<) |- G_x(y) === F(y)(G_x initialSegment(y)(A)(<))) subproof {
812812
assume(y initialSegment(x)(A)(<))
813813

814-
val `y ∈ dom(G_z)` = have(y initialSegment(z)(A)(<) |- y dom(G_(z))) by Congruence.from(`dom(G_y)` of (y := z))
814+
val `y ∈ dom(G_z)` = have((z initialSegment(x)(A)(<), y initialSegment(z)(A)(<)) |- y dom(G_(z))) by Congruence.from(`dom(G_y)` of (y := z))
815815

816816
/**
817817
* We show that if `y < z` then `G_z(y) = F(y, G_x ↾ A_<y)`.

lisa-sets/src/main/scala/lisa/maths/SetTheory/Ordinals/TransfiniteRecursion.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ object TransfiniteRecursion extends lisa.Main {
4343
)
4444

4545
// It remains to replace `initialSegment(β, α, <)` with `β` under the binders.
46-
have(G(β) === F(β)(G initialSegment(β)(α)(membershipRelation(α))) |- (G(β) === F(β)(G β))) by Congruence.from(Ordinal.ordinalInitialSegment)
46+
have((G(β) === F(β)(G initialSegment(β)(α)(membershipRelation(α))), β α) |- (G(β) === F(β)(G β))) by Congruence.from(Ordinal.ordinalInitialSegment)
4747
thenHave(β α ==> (G(β) === F(β)(G initialSegment(β)(α)(membershipRelation(α)))) |- β α ==> (G(β) === F(β)(G β))) by Tautology
4848
thenHave((β, β α ==> (G(β) === F(β)(G initialSegment(β)(α)(membershipRelation(α))))) |- β α ==> (G(β) === F(β)(G β))) by LeftForall
4949
thenHave((β, β α ==> (G(β) === F(β)(G initialSegment(β)(α)(membershipRelation(α))))) |- (β, β α ==> (G(β) === F(β)(G β)))) by RightForall

0 commit comments

Comments
 (0)