From 6e355f4d64a3c14d9a4fe527aa7bce9a012d906c Mon Sep 17 00:00:00 2001 From: Katja Goltsova <katja.goltsova@protonmail.com> Date: Wed, 17 Aug 2022 18:09:08 +0200 Subject: [PATCH] Prove in Peano that x+Sy = Sx+y --- .../scala/lisa/proven/mathematics/Peano.scala | 146 +++++++++++++++++- 1 file changed, 145 insertions(+), 1 deletion(-) diff --git a/src/main/scala/lisa/proven/mathematics/Peano.scala b/src/main/scala/lisa/proven/mathematics/Peano.scala index 12275ae0..06fcae02 100644 --- a/src/main/scala/lisa/proven/mathematics/Peano.scala +++ b/src/main/scala/lisa/proven/mathematics/Peano.scala @@ -4,8 +4,8 @@ import lisa.kernel.fol.FOL.* import lisa.kernel.proof.RunningTheory import lisa.kernel.proof.SCProof import lisa.kernel.proof.SequentCalculus.* -import lisa.proven.tactics.ProofTactics.* import lisa.proven.PeanoArithmeticsLibrary +import lisa.proven.tactics.ProofTactics.* import lisa.utils.Helpers.{_, given} import lisa.utils.Library @@ -19,6 +19,19 @@ object Peano { def main(args: Array[String]): Unit = {} ///////////////////////////////////////////////////////////////////// + def instantiateForallAxiom(ax: Axiom, t: Term): SCProof = { + val formula = ax.ax + require(formula.isInstanceOf[BinderFormula] && formula.asInstanceOf[BinderFormula].label == Forall) + val forall = ax.ax.asInstanceOf[BinderFormula] + instantiateForall(SCProof(IndexedSeq(), IndexedSeq(ax))) + val tempVar = VariableLabel(freshId(formula.freeVariables.map(_.id), "x")) + val instantiated = instantiateBinder(forall, t) + val p1 = Hypothesis(instantiated |- instantiated, instantiated) + val p2 = LeftForall(formula |- instantiated, 0, instantiateBinder(forall, tempVar), tempVar, t) + val p3 = Cut(() |- instantiated, -1, 1, formula) + Proof(IndexedSeq(p1, p2, p3), IndexedSeq(ax)) + } + THEOREM("x + 0 = 0 + x") of "∀x. plus(x, zero) === plus(zero, x)" PROOF { val refl0: SCProofStep = RightRefl(() |- s(x) === s(x), s(x) === s(x)) val subst1 = RightSubstEq((x === plus(zero, x)) |- s(x) === s(plus(zero, x)), 0, (x, plus(zero, x)) :: Nil, LambdaTermFormula(Seq(y), s(x) === s(y))) @@ -127,4 +140,135 @@ object Peano { ) } using (ax"ax4plusSuccessor", ax"ax3neutral", ax"ax7induction") show + + THEOREM("switch successor") of "∀y. ∀x. plus(x, s(y)) === plus(s(x), y)" PROOF { + //////////////////////////////////// Base: x + S0 = Sx + 0 /////////////////////////////////////////////// + val base0 = { + // x + 0 = x + val xEqXPlusZero0 = SCSubproof(instantiateForallAxiom(ax"ax3neutral", x), IndexedSeq(-1)) + // Sx + 0 = Sx + val succXEqSuccXPlusZero1 = SCSubproof(instantiateForallAxiom(ax"ax3neutral", s(x)), IndexedSeq(-1)) + // x + S0 = S(x + 0) + val xPlusSuccZero2 = SCSubproof(instantiateForall(instantiateForallAxiom(ax"ax4plusSuccessor", x), zero), IndexedSeq(-2)) + + // ------------------- x + 0 = x, Sx + 0 = Sx, x + S0 = S(x + 0) |- Sx + 0 = x + S0 --------------------- + val succX3 = RightRefl(() |- s(x) === s(x), s(x) === s(x)) + val substEq4 = RightSubstEq( + Set(s(x) === plus(s(x), zero), x === plus(x, zero)) |- plus(s(x), zero) === s(plus(x, zero)), + 3, + (s(x), plus(s(x), zero)) :: (VariableTerm(x), plus(x, zero)) :: Nil, + LambdaTermFormula(Seq(y, z), y === s(z)) + ) + val substEq5 = RightSubstEq( + Set(s(x) === plus(s(x), zero), x === plus(x, zero), s(plus(x, zero)) === plus(x, s(zero))) |- plus(s(x), zero) === plus(x, s(zero)), + 4, + (s(plus(x, zero)), plus(x, s(zero))) :: Nil, + LambdaTermFormula(Seq(z), plus(s(x), zero) === z) + ) + // ------------------------------------------------------------------------------------------------------- + val cut6 = Cut(Set(s(x) === plus(s(x), zero), x === plus(x, zero)) |- plus(s(x), zero) === plus(x, s(zero)), 2, 5, s(plus(x, zero)) === plus(x, s(zero))) + val cut7 = Cut(x === plus(x, zero) |- plus(s(x), zero) === plus(x, s(zero)), 1, 6, s(x) === plus(s(x), zero)) + val cut8 = Cut(() |- plus(s(x), zero) === plus(x, s(zero)), 0, 7, x === plus(x, zero)) + SCSubproof( + SCProof( + IndexedSeq(xEqXPlusZero0, succXEqSuccXPlusZero1, xPlusSuccZero2, succX3, substEq4, substEq5, cut6, cut7, cut8), + IndexedSeq(ax"ax3neutral", ax"ax4plusSuccessor") + ), + IndexedSeq(-1, -2) + ) + } + + val (x1, y1, z1) = + (VariableLabel("x1"), VariableLabel("y1"), VariableLabel("z1")) + + /////////////// Induction step: ∀y. (x + Sy === Sx + y) ==> (x + SSy === Sx + Sy) //////////////////// + val inductionStep1 = { + // x + SSy = S(x + Sy) + val moveSuccessor0 = SCSubproof(instantiateForall(instantiateForallAxiom(ax"ax4plusSuccessor", x), s(y)), IndexedSeq(-2)) + + // Sx + Sy = S(Sx + y) + val moveSuccessor1 = SCSubproof(instantiateForall(instantiateForallAxiom(ax"ax4plusSuccessor", s(x)), y), IndexedSeq(-2)) + + // ----------- x + SSy = S(x + Sy), x + Sy = Sx + y, S(Sx + y) = Sx + Sy |- x + SSy = Sx + Sy ------------ + val middleEq2 = RightRefl(() |- s(plus(x, s(y))) === s(plus(x, s(y))), s(plus(x, s(y))) === s(plus(x, s(y)))) + val substEq3 = + RightSubstEq( + Set(plus(x, s(y)) === plus(s(x), y)) |- s(plus(x, s(y))) === s(plus(s(x), y)), + 2, + (plus(x, s(y)), plus(s(x), y)) :: Nil, + LambdaTermFormula(Seq(z1), s(plus(x, s(y))) === s(z1)) + ) + val substEq4 = + RightSubstEq( + Set(plus(x, s(y)) === plus(s(x), y), plus(x, s(s(y))) === s(plus(x, s(y)))) |- plus(x, s(s(y))) === s(plus(s(x), y)), + 3, + (plus(x, s(s(y))), s(plus(x, s(y)))) :: Nil, + LambdaTermFormula(Seq(z1), z1 === s(plus(s(x), y))) + ) + val substEq5 = + RightSubstEq( + Set(plus(x, s(s(y))) === s(plus(x, s(y))), plus(x, s(y)) === plus(s(x), y), s(plus(s(x), y)) === plus(s(x), s(y))) |- plus(x, s(s(y))) === plus(s(x), s(y)), + 4, + (s(plus(s(x), y)), plus(s(x), s(y))) :: Nil, + LambdaTermFormula(Seq(z1), plus(x, s(s(y))) === z1) + ) + // ------------------------------------------------------------------------------------------------------- + val cut6 = Cut(Set(plus(x, s(y)) === plus(s(x), y), s(plus(s(x), y)) === plus(s(x), s(y))) |- plus(x, s(s(y))) === plus(s(x), s(y)), 0, 5, plus(x, s(s(y))) === s(plus(x, s(y)))) + val cut7 = Cut(plus(x, s(y)) === plus(s(x), y) |- plus(x, s(s(y))) === plus(s(x), s(y)), 1, 6, s(plus(s(x), y)) === plus(s(x), s(y))) + val implies8 = RightImplies(() |- (plus(x, s(y)) === plus(s(x), y)) ==> (plus(x, s(s(y))) === plus(s(x), s(y))), 7, plus(x, s(y)) === plus(s(x), y), plus(x, s(s(y))) === plus(s(x), s(y))) + val forall9 = RightForall( + () |- forall(y, (plus(x, s(y)) === plus(s(x), y)) ==> (plus(x, s(s(y))) === plus(s(x), s(y)))), + 8, + (plus(x, s(y)) === plus(s(x), y)) ==> (plus(x, s(s(y))) === plus(s(x), s(y))), + y + ) + SCSubproof( + SCProof( + IndexedSeq(moveSuccessor0, moveSuccessor1, middleEq2, substEq3, substEq4, substEq5, cut6, cut7, implies8, forall9), + IndexedSeq(ax"ax3neutral", ax"ax4plusSuccessor") + ), + IndexedSeq(-1, -2) + ) + } + + val inductionOnY2 = Rewrite(() |- (sPhi(zero) /\ forall(y, sPhi(y) ==> sPhi(s(y)))) ==> forall(y, sPhi(y)), -3) + val inductionInstance3 = InstPredSchema( + () |- + ((plus(s(x), zero) === plus(x, s(zero))) /\ + forall(y, (plus(x, s(y)) === plus(s(x), y)) ==> (plus(x, s(s(y))) === plus(s(x), s(y))))) ==> + forall(y, plus(x, s(y)) === plus(s(x), y)), + 2, + Map(sPhi -> LambdaTermFormula(Seq(y), plus(x, s(y)) === plus(s(x), y))) + ) + val inductionPremise4 = RightAnd( + () |- (plus(x, s(zero)) === plus(s(x), zero)) /\ + forall(y, (plus(x, s(y)) === plus(s(x), y)) ==> (plus(x, s(s(y))) === plus(s(x), s(y)))), + Seq(0, 1), + Seq(plus(x, s(zero)) === plus(s(x), zero), forall(y, (plus(x, s(y)) === plus(s(x), y)) ==> (plus(x, s(s(y))) === plus(s(x), s(y))))) + ) + val conclusion5 = hypothesis(forall(y, plus(x, s(y)) === plus(s(x), y))) + val inductionInstanceOnTheLeft6 = LeftImplies( + ((plus(s(x), zero) === plus(x, s(zero))) /\ + forall(y, (plus(x, s(y)) === plus(s(x), y)) ==> (plus(x, s(s(y))) === plus(s(x), s(y))))) ==> + forall(y, plus(x, s(y)) === plus(s(x), y)) + |- forall(y, plus(x, s(y)) === plus(s(x), y)), + 4, + 5, + (plus(x, s(zero)) === plus(s(x), zero)) /\ forall(y, (plus(x, s(y)) === plus(s(x), y)) ==> (plus(x, s(s(y))) === plus(s(x), s(y)))), + forall(y, plus(x, s(y)) === plus(s(x), y)) + ) + val inductionResult7 = Cut( + () |- forall(y, plus(x, s(y)) === plus(s(x), y)), + 3, + 6, + ((plus(x, s(zero)) === plus(s(x), zero)) /\ forall(y, (plus(x, s(y)) === plus(s(x), y)) ==> (plus(x, s(s(y))) === plus(s(x), s(y))))) ==> forall(y, plus(x, s(y)) === plus(s(x), y)) + ) + val addForall8 = RightForall(() |- forall(x, forall(y, plus(x, s(y)) === plus(s(x), y))), 7, forall(y, plus(x, s(y)) === plus(s(x), y)), x) + val proof: SCProof = Proof( + IndexedSeq(base0, inductionStep1, inductionOnY2, inductionInstance3, inductionPremise4, conclusion5, inductionInstanceOnTheLeft6, inductionResult7, addForall8), + IndexedSeq(ax"ax3neutral", ax"ax4plusSuccessor", ax"ax7induction") + ) + proof + } using (ax"ax3neutral", ax"ax4plusSuccessor", ax"ax7induction") + show } -- GitLab