diff --git a/src/main/scala/lisa/kernel/fol/FormulaDefinitions.scala b/src/main/scala/lisa/kernel/fol/FormulaDefinitions.scala index d9561a39722ccfb5b7bdea4ca185f19066b98484..053be248ab164361b41091eea38be6c92da538ef 100644 --- a/src/main/scala/lisa/kernel/fol/FormulaDefinitions.scala +++ b/src/main/scala/lisa/kernel/fol/FormulaDefinitions.scala @@ -11,9 +11,12 @@ private[fol] trait FormulaDefinitions extends FormulaLabelDefinitions with TermD * A formula is a tree whose nodes are either terms or labeled by predicates or logical connectors. */ sealed abstract class Formula extends TreeWithLabel[FormulaLabel] { - def predicates: Set[ConstantPredicateLabel] - def functions: Set[ConstantFunctionLabel] - //def predicatesSchemas: Set[PredicateLabel] = predicates filter { case _: ConstantPredicateLabel => false; case _: SchematicPredicateLabel => true } + + def constantFunctions: Set[ConstantFunctionLabel] + def schematicFunctions: Set[SchematicFunctionLabel] + + def constantPredicates: Set[ConstantPredicateLabel] + def schematicPredicates: Set[SchematicPredicateLabel] } /** @@ -22,12 +25,17 @@ private[fol] trait FormulaDefinitions extends FormulaLabelDefinitions with TermD final case class PredicateFormula(label: PredicateLabel, args: Seq[Term]) extends Formula { override def freeVariables: Set[VariableLabel] = args.foldLeft(Set.empty[VariableLabel])((prev, next) => prev union next.freeVariables) - override def predicates: Set[ConstantPredicateLabel] = label match { + override def constantPredicates: Set[ConstantPredicateLabel] = label match { case l: ConstantPredicateLabel => Set(l) case l: SchematicPredicateLabel => Set() } + override def schematicPredicates: Set[SchematicPredicateLabel] = label match { + case l: ConstantPredicateLabel => Set() + case l: SchematicPredicateLabel => Set(l) + } - override def functions: Set[ConstantFunctionLabel] = args.foldLeft(Set.empty[ConstantFunctionLabel])((prev, next) => prev union next.functions) + override def constantFunctions: Set[ConstantFunctionLabel] = args.foldLeft(Set.empty[ConstantFunctionLabel])((prev, next) => prev union next.constantFunctions) + override def schematicFunctions: Set[SchematicFunctionLabel] = args.foldLeft(Set.empty[SchematicFunctionLabel])((prev, next) => prev union next.schematicFunctions) } @@ -37,9 +45,12 @@ private[fol] trait FormulaDefinitions extends FormulaLabelDefinitions with TermD final case class ConnectorFormula(label: ConnectorLabel, args: Seq[Formula]) extends Formula { override def freeVariables: Set[VariableLabel] = args.foldLeft(Set.empty[VariableLabel])((prev, next) => prev union next.freeVariables) - override def predicates: Set[ConstantPredicateLabel] = args.foldLeft(Set.empty[ConstantPredicateLabel])((prev, next) => prev union next.predicates) - override def functions: Set[ConstantFunctionLabel] = args.foldLeft(Set.empty[ConstantFunctionLabel])((prev, next) => prev union next.functions) + override def constantFunctions: Set[ConstantFunctionLabel] = args.foldLeft(Set.empty[ConstantFunctionLabel])((prev, next) => prev union next.constantFunctions) + override def schematicFunctions: Set[SchematicFunctionLabel] = args.foldLeft(Set.empty[SchematicFunctionLabel])((prev, next) => prev union next.schematicFunctions) + + override def constantPredicates: Set[ConstantPredicateLabel] = args.foldLeft(Set.empty[ConstantPredicateLabel])((prev, next) => prev union next.constantPredicates) + override def schematicPredicates: Set[SchematicPredicateLabel] = args.foldLeft(Set.empty[SchematicPredicateLabel])((prev, next) => prev union next.schematicPredicates) } /** @@ -48,9 +59,11 @@ private[fol] trait FormulaDefinitions extends FormulaLabelDefinitions with TermD final case class BinderFormula(label: BinderLabel, bound: VariableLabel, inner: Formula) extends Formula { override def freeVariables: Set[VariableLabel] = inner.freeVariables - bound - override def predicates: Set[ConstantPredicateLabel] = inner.predicates + override def constantFunctions: Set[ConstantFunctionLabel] = inner.constantFunctions + override def schematicFunctions: Set[SchematicFunctionLabel] = inner.schematicFunctions - override def functions: Set[ConstantFunctionLabel] = inner.functions + override def constantPredicates: Set[ConstantPredicateLabel] = inner.constantPredicates + override def schematicPredicates: Set[SchematicPredicateLabel] = inner.schematicPredicates } /** diff --git a/src/main/scala/lisa/kernel/fol/TermDefinitions.scala b/src/main/scala/lisa/kernel/fol/TermDefinitions.scala index 25c23e0e72aab95c21e93f1c7d0f1121d958388b..33a9d54e8457a89b49a195e29f052953a0b8ddf3 100644 --- a/src/main/scala/lisa/kernel/fol/TermDefinitions.scala +++ b/src/main/scala/lisa/kernel/fol/TermDefinitions.scala @@ -10,7 +10,8 @@ private[fol] trait TermDefinitions extends TermLabelDefinitions { def freeVariables: Set[VariableLabel] - def functions: Set[ConstantFunctionLabel] + def constantFunctions: Set[ConstantFunctionLabel] + def schematicFunctions: Set[SchematicFunctionLabel] } @@ -30,7 +31,8 @@ private[fol] trait TermDefinitions extends TermLabelDefinitions { final case class VariableTerm(label: VariableLabel) extends Term { override def freeVariables: Set[VariableLabel] = Set(label) - override def functions: Set[ConstantFunctionLabel] = Set.empty + override def constantFunctions: Set[ConstantFunctionLabel] = Set.empty + override def schematicFunctions: Set[SchematicFunctionLabel] = Set.empty } /** @@ -44,9 +46,13 @@ private[fol] trait TermDefinitions extends TermLabelDefinitions { override def freeVariables: Set[VariableLabel] = args.foldLeft(Set.empty[VariableLabel])((prev, next) => prev union next.freeVariables) - override def functions: Set[ConstantFunctionLabel] = label match { - case l:ConstantFunctionLabel => args.foldLeft(Set.empty[ConstantFunctionLabel])((prev, next) => prev union next.functions) + l - case l:SchematicFunctionLabel => args.foldLeft(Set.empty[ConstantFunctionLabel])((prev, next) => prev union next.functions) + override def constantFunctions: Set[ConstantFunctionLabel] = label match { + case l:ConstantFunctionLabel => args.foldLeft(Set.empty[ConstantFunctionLabel])((prev, next) => prev union next.constantFunctions) + l + case l:SchematicFunctionLabel => args.foldLeft(Set.empty[ConstantFunctionLabel])((prev, next) => prev union next.constantFunctions) + } + override def schematicFunctions: Set[SchematicFunctionLabel] = label match { + case l:ConstantFunctionLabel => args.foldLeft(Set.empty[SchematicFunctionLabel])((prev, next) => prev union next.schematicFunctions) + case l:SchematicFunctionLabel => args.foldLeft(Set.empty[SchematicFunctionLabel])((prev, next) => prev union next.schematicFunctions) + l } val arity: Int = args.size diff --git a/src/main/scala/lisa/kernel/proof/Judgement.scala b/src/main/scala/lisa/kernel/proof/Judgement.scala new file mode 100644 index 0000000000000000000000000000000000000000..20f6740f21583ab0cc9e52ca229b8ce9713360c9 --- /dev/null +++ b/src/main/scala/lisa/kernel/proof/Judgement.scala @@ -0,0 +1,71 @@ +package lisa.kernel.proof + +import lisa.kernel.proof.RunningTheory + +/** + * The judgement (or verdict) of a proof checking procedure. + * Typically, see [[SCProofChecker.checkSingleSCStep]] and [[SCProofChecker.checkSCProof]]. + */ +sealed abstract class SCProofCheckerJudgement { + import SCProofCheckerJudgement.* + + /** + * Whether this judgement is positive -- the proof is concluded to be valid; + * or negative -- the proof checker couldn't certify the validity of this proof. + * @return An instance of either [[SCValidProof]] or [[SCInvalidProof]] + */ + def isValid: Boolean = this match { + case SCValidProof => true + case _: SCInvalidProof => false + } +} + +object SCProofCheckerJudgement { + /** + * A positive judgement. + */ + case object SCValidProof extends SCProofCheckerJudgement + + /** + * A negative judgement. + * @param path The path of the error, expressed as indices + * @param message The error message that hints about the first error encountered + */ + case class SCInvalidProof(path: Seq[Int], message: String) extends SCProofCheckerJudgement +} + + +/** + * The judgement (or verdict) of a running theory. + */ +sealed abstract class RunningTheoryJudgement[J<:RunningTheory#Justification] { + import RunningTheoryJudgement.* + + /** + * Whether this judgement is positive -- the justification could be imported into the running theory; + * or negative -- the justification is not suitable to be imported in the theory. + * @return An instance of either [[ValidJustification]] or [[InvalidJustification]] + */ + def isValid: Boolean = this match { + case _: ValidJustification[?] => true + case _: InvalidJustification[?] => false + } + def get:J = this match { + case ValidJustification(just) => just + case InvalidJustification(message, error) => None.get + } +} + +object RunningTheoryJudgement { + /** + * A positive judgement. + */ + case class ValidJustification[J<:RunningTheory#Justification](just:J) extends RunningTheoryJudgement[J] + + /** + * A negative judgement. + * @param error If the justification is rejected because the proof is wrong, will contain the error in the proof. + * @param message The error message that hints about the first error encountered + */ + case class InvalidJustification[J<:RunningTheory#Justification](message: String, error: Option[SCProofCheckerJudgement.SCInvalidProof]) extends RunningTheoryJudgement[J] +} diff --git a/src/main/scala/lisa/kernel/proof/RunningTheory.scala b/src/main/scala/lisa/kernel/proof/RunningTheory.scala index 9c87f3aff0c755478a3d53c729e65942fb15eea0..a67c56156fce6623033c917b3d545e0a35176c7e 100644 --- a/src/main/scala/lisa/kernel/proof/RunningTheory.scala +++ b/src/main/scala/lisa/kernel/proof/RunningTheory.scala @@ -7,6 +7,7 @@ import lisa.kernel.fol.FOL.* import scala.collection.mutable.Map as mMap import scala.collection.mutable.Set as mSet import scala.collection.immutable.Set +import lisa.kernel.proof.RunningTheoryJudgement.* /** * This class describes the theory, i.e. the context and language, in which theorems are proven. @@ -26,11 +27,11 @@ class RunningTheory { /** * A theorem encapsulate a sequent and assert that this sequent has been correctly proven and may be used safely in further proofs. */ - final case class Theorem private[RunningTheory](proposition: Sequent) extends Justification + final case class Theorem private[RunningTheory](name:String, proposition: Sequent) extends Justification /** * An axiom is any formula that is assumed and considered true within the theory. It can freely be used later in any proof. */ - final case class Axiom private[RunningTheory](ax: Formula) extends Justification + final case class Axiom private[RunningTheory](name:String, ax: Formula) extends Justification /** * A definition can be either a PredicateDefinition or a FunctionDefinition. @@ -57,7 +58,8 @@ class RunningTheory { final case class FunctionDefinition private[RunningTheory](label: ConstantFunctionLabel, args: Seq[VariableLabel], out: VariableLabel, phi: Formula) extends Definition - private[proof] val theoryAxioms : mSet[Axiom] = mSet.empty + private[proof] val theoryAxioms : mMap[String, Axiom] = mMap.empty + private[proof] val theorems : mMap[String, Theorem] = mMap.empty private[proof] val funDefinitions: mMap[FunctionLabel, Option[FunctionDefinition]] = mMap.empty private[proof] val predDefinitions: mMap[PredicateLabel, Option[PredicateDefinition]] = mMap(equality -> None) @@ -71,17 +73,27 @@ class RunningTheory { def isAcceptedPredicateLabel(label:PredicateLabel): Boolean = predDefinitions.contains(label) /** - * From a given proof, if it is true in the Running theory, returns a theorem that is valid in the given theory. + * From a given proof, if it is true in the Running theory, add that theorem to the theory and returns it. * The proof's imports must be justified by the list of justification, and the conclusion of the theorem * can't contain symbols that do not belong to the theory. * @param justifications The list of justifications of the proof's imports. * @param p The proof of the desired Theorem. * @return A Theorem if the proof is correct, None else */ - def proofToTheorem(p: SCProof, justifications:Seq[Justification]): Option[this.Theorem] = - if (checkProofWithinTheory(p, justifications) && belongsToTheory(p.conclusion)) - Some(Theorem(p.conclusion)) - else None + def proofToTheorem(name:String, proof: SCProof, justifications:Seq[Justification]): RunningTheoryJudgement[this.Theorem] = + if (proof.imports.forall(i => justifications.exists( j => isSameSequent(i, sequentFromJustification(j))))) + if (belongsToTheory(proof.conclusion)) + val r = SCProofChecker.checkSCProof(proof) + r match { + case SCProofCheckerJudgement.SCValidProof => + val thm = Theorem(name, proof.conclusion) + theorems.update(name, thm) + RunningTheoryJudgement.ValidJustification(thm) + case r @ SCProofCheckerJudgement.SCInvalidProof(path, message) => + InvalidJustification("The given proof is incorrect: " + message, Some(r)) + } + else InvalidJustification("All symbols in the conclusion of the proof must belong to the theory. You need to add missing symbols to the theory.", None) + else InvalidJustification("Not all imports of the proof are correctly justified.", None) /** @@ -92,14 +104,16 @@ class RunningTheory { * @param phi The formula defining the predicate. * @return A definition object if the parameters are correct, */ - def makePredicateDefinition(label: ConstantPredicateLabel, args: Seq[VariableLabel], phi: Formula): Option[this.PredicateDefinition] = { - if (belongsToTheory(phi) && !isAcceptedPredicateLabel(label)) { - val newDef = PredicateDefinition(label, args, phi) - predDefinitions.update(label, Some(newDef)) - Some(newDef) - } else { - None - } + def makePredicateDefinition(label: ConstantPredicateLabel, args: Seq[VariableLabel], phi: Formula): RunningTheoryJudgement[this.PredicateDefinition] = { + if (belongsToTheory(phi)) + if (!isAcceptedPredicateLabel(label)) + if (phi.freeVariables.isEmpty && phi.schematicFunctions.isEmpty && phi.schematicPredicates.isEmpty) + val newDef = PredicateDefinition(label, args, phi) + predDefinitions.update(label, Some(newDef)) + RunningTheoryJudgement.ValidJustification(newDef) + else InvalidJustification("The definition is not allowed to contain schematic symbols or free variables.", None) + else InvalidJustification("The specified symbol is already part of the theory and can't be redefined.", None) + else InvalidJustification("All symbols in the conclusion of the proof must belong to the theory. You need to add missing symbols to the theory.", None) } /** @@ -116,49 +130,38 @@ class RunningTheory { * @param phi The formula defining the predicate. * @return A definition object if the parameters are correct, */ - def makeFunctionDefinition(proof: SCProof, justifications:Seq[Justification], label: ConstantFunctionLabel, args: Seq[VariableLabel], out: VariableLabel, phi: Formula): Option[this.FunctionDefinition] = { - if (belongsToTheory(phi) && !isAcceptedFunctionLabel(label) && checkProofWithinTheory(proof, justifications)) { - - proof.conclusion match{ - case Sequent(l, r) if l.isEmpty && r.size == 1 => - val subst = bindAll(Forall, args, BinderFormula(ExistsOne, out, phi)) - val subst2 = bindAll(Forall, args.reverse, BinderFormula(ExistsOne, out, phi)) - if (isSame(r.head, subst) || isSame(r.head, subst2)){ - val newDef = FunctionDefinition(label, args, out, phi) - funDefinitions.update(label, Some(newDef)) - Some(newDef) - } - else None - - case _ => None - } - } else { - None - } + def makeFunctionDefinition(proof: SCProof, justifications:Seq[Justification], label: ConstantFunctionLabel, args: Seq[VariableLabel], out: VariableLabel, phi: Formula): RunningTheoryJudgement[this.FunctionDefinition] = { + if (belongsToTheory(phi)) + if (!isAcceptedFunctionLabel(label)) + if (phi.freeVariables.isEmpty && phi.schematicFunctions.isEmpty && phi.schematicPredicates.isEmpty) + if (proof.imports.forall(i => justifications.exists( j => isSameSequent(i, sequentFromJustification(j))))) + val r = SCProofChecker.checkSCProof(proof) + r match { + case SCProofCheckerJudgement.SCValidProof => + proof.conclusion match{ + case Sequent(l, r) if l.isEmpty && r.size == 1 => + val subst = bindAll(Forall, args, BinderFormula(ExistsOne, out, phi)) + val subst2 = bindAll(Forall, args.reverse, BinderFormula(ExistsOne, out, phi)) + if (isSame(r.head, subst) || isSame(r.head, subst2)){ + val newDef = FunctionDefinition(label, args, out, phi) + funDefinitions.update(label, Some(newDef)) + RunningTheoryJudgement.ValidJustification(newDef) + } + else InvalidJustification("The proof is correct but its conclusion does not correspond to a definition for for the formula phi.", None) + case _ => InvalidJustification("The conclusion of the proof must have an empty left hand side, and a single formula on the right hand side.", None) + } + case r @ SCProofCheckerJudgement.SCInvalidProof(path, message) => InvalidJustification("The given proof is incorrect: " + message, Some(r)) + } + else InvalidJustification("Not all imports of the proof are correctly justified.", None) + else InvalidJustification("The definition is not allowed to contain schematic symbols or free variables.", None) + else InvalidJustification("The specified symbol is already part of the theory and can't be redefined.", None) + else InvalidJustification("All symbols in the conclusion of the proof must belong to the theory. You need to add missing symbols to the theory.", None) } - - /** - * Verify is a proof is correct withing a given Theory. It separately verifies if the proof is correct from - * a pure sequent calculus point of view, and if definitions and theorem imported into the proof are indeed - * part of the theory. - * - */ - def checkProofWithinTheory(proof: SCProof, justifications: Seq[Justification]): Boolean = { - - if (belongsToTheory(proof.conclusion)){ - if (proof.imports.forall(i => justifications.exists( j => isSameSequent(i, sequentFromJustification(j))) )) - true - else - false - } - else false - } - private def sequentFromJustification(j:Justification): Sequent = j match { - case Theorem(proposition) => proposition - case Axiom(ax) => Sequent(Set.empty, Set(ax)) + case Theorem(name, proposition) => proposition + case Axiom(name, ax) => Sequent(Set.empty, Set(ax)) case PredicateDefinition(label, args, phi) => val inner = ConnectorFormula(Iff, Seq(PredicateFormula(label, args.map(VariableTerm.apply)), phi)) Sequent(Set(), Set(bindAll(Forall, args, inner))) @@ -194,8 +197,8 @@ class RunningTheory { } def makeFormulaBelongToTheory(phi:Formula) : Unit = { - phi.predicates.foreach(addSymbol) - phi.functions.foreach(addSymbol) + phi.constantPredicates.foreach(addSymbol) + phi.constantFunctions.foreach(addSymbol) } /** * Verify if a given term belongs to some language @@ -232,9 +235,9 @@ class RunningTheory { * @param f the new axiom to be added. * @return true if the axiom was added to the theory, false else. */ - def addAxiom(f:Formula):Boolean = { + def addAxiom(name:String, f:Formula):Boolean = { if (belongsToTheory(f)){ - theoryAxioms.add(Axiom(f)) + theoryAxioms.update(name, Axiom(name, f)) true } else false @@ -258,14 +261,17 @@ class RunningTheory { * Public accessor to the current set of axioms of the theory * @return the current set of axioms of the theory */ - def getAxioms: List[Axiom] = theoryAxioms.toList + def axiomsList: Iterable[Axiom] = theoryAxioms.values /** * Verify if a given formula is an axiom of the theory * @param f the candidate axiom * @return wether f is an axiom of the theory */ - def isAxiom(f:Formula): Boolean = theoryAxioms.exists(a => isSame(a.ax,f)) + def isAxiom(f:Formula): Boolean = theoryAxioms.exists(a => isSame(a._2.ax,f)) + def getAxiom(f:Formula): Option[Axiom] = theoryAxioms.find(a => isSame(a._2.ax,f)).map(_._2) + def getAxiom(name:String): Option[Axiom] = theoryAxioms.get(name) + def getTheorem(name:String): Option[Theorem] = theorems.get(name) } object RunningTheory { diff --git a/src/main/scala/lisa/kernel/proof/SCProofCheckerJudgement.scala b/src/main/scala/lisa/kernel/proof/SCProofCheckerJudgement.scala deleted file mode 100644 index bf81d106f20b8587e6cd263bdefa6e6256f5e6b0..0000000000000000000000000000000000000000 --- a/src/main/scala/lisa/kernel/proof/SCProofCheckerJudgement.scala +++ /dev/null @@ -1,33 +0,0 @@ -package lisa.kernel.proof - -/** - * The judgement (or verdict) of a proof checking procedure. - * Typically, see [[SCProofChecker.checkSingleSCStep]] and [[SCProofChecker.checkSCProof]]. - */ -sealed abstract class SCProofCheckerJudgement { - import SCProofCheckerJudgement.* - - /** - * Whether this judgement is positive -- the proof is concluded to be valid; - * or negative -- the proof checker couldn't certify the validity of this proof. - * @return An instance of either [[SCValidProof]] or [[SCInvalidProof]] - */ - def isValid: Boolean = this match { - case SCValidProof => true - case _: SCInvalidProof => false - } -} - -object SCProofCheckerJudgement { - /** - * A positive judgement. - */ - case object SCValidProof extends SCProofCheckerJudgement - - /** - * A negative judgement. - * @param path The path of the error, expressed as indices - * @param message The error message that hints about the first error encountered - */ - case class SCInvalidProof(path: Seq[Int], message: String) extends SCProofCheckerJudgement -} diff --git a/src/main/scala/lisa/settheory/SetTheoryDefinitions.scala b/src/main/scala/lisa/settheory/SetTheoryDefinitions.scala index 6b6d1de060e2cb0c40a0521f3077dea7ec4561f0..5df53d836163af787707961fad9bbf40042e4032 100644 --- a/src/main/scala/lisa/settheory/SetTheoryDefinitions.scala +++ b/src/main/scala/lisa/settheory/SetTheoryDefinitions.scala @@ -9,7 +9,7 @@ import lisa.KernelHelpers.{given, _} */ private[settheory] trait SetTheoryDefinitions{ type Axiom = Formula - def axioms: Set[Axiom] = Set.empty + def axioms: Set[(String, Axiom)] = Set.empty private[settheory] final val (x, y, z, a, b) = (VariableLabel("x"), VariableLabel("y"), VariableLabel("z"), VariableLabel("A"), VariableLabel("B")) final val sPhi = SchematicPredicateLabel("P", 2) diff --git a/src/main/scala/lisa/settheory/SetTheoryTGAxioms.scala b/src/main/scala/lisa/settheory/SetTheoryTGAxioms.scala index c1a92a892a5097b1dac2357d11123da93acff40d..cc8cf2e5f028532fffcdf9b8aaca7540317a627c 100644 --- a/src/main/scala/lisa/settheory/SetTheoryTGAxioms.scala +++ b/src/main/scala/lisa/settheory/SetTheoryTGAxioms.scala @@ -12,8 +12,8 @@ private[settheory] trait SetTheoryTGAxioms extends SetTheoryZFAxioms { ) ) - runningSetTheory.addAxiom(tarskiAxiom) + runningSetTheory.addAxiom("TarskiAxiom", tarskiAxiom) - override def axioms: Set[Axiom] = super.axioms + tarskiAxiom + override def axioms: Set[(String, Axiom)] = super.axioms + (("TarskiAxiom", tarskiAxiom)) } \ No newline at end of file diff --git a/src/main/scala/lisa/settheory/SetTheoryZAxioms.scala b/src/main/scala/lisa/settheory/SetTheoryZAxioms.scala index 46071edaa86050f87444b5b555215699209f666e..5ccf623b9844b7ecdd18e5f85c11c909f58e4f05 100644 --- a/src/main/scala/lisa/settheory/SetTheoryZAxioms.scala +++ b/src/main/scala/lisa/settheory/SetTheoryZAxioms.scala @@ -18,12 +18,20 @@ private[settheory] trait SetTheoryZAxioms extends SetTheoryDefinitions { final val comprehensionSchema: Axiom = forall(z, exists(y, forall(x, in(x,y) <=> (in(x,z) /\ sPhi(x,z))))) - private val zAxioms: Set[Axiom] = Set(emptySetAxiom, extensionalityAxiom, pairAxiom, unionAxiom, powerAxiom, foundationAxiom, comprehensionSchema) + private val zAxioms: Set[(String, Axiom)] = Set( + ("EmptySet", emptySetAxiom), + ("extensionalityAxiom", extensionalityAxiom), + ("pairAxiom", pairAxiom), + ("unionAxiom", unionAxiom), + ("powerAxiom", powerAxiom), + ("foundationAxiom", foundationAxiom), + ("comprehensionSchema", comprehensionSchema) + ) - zAxioms.foreach(a => runningSetTheory.addAxiom(a)) + zAxioms.foreach(a => runningSetTheory.addAxiom(a._1, a._2)) - override def axioms: Set[Axiom] = super.axioms ++ zAxioms + override def axioms: Set[(String, Axiom)] = super.axioms ++ zAxioms } \ No newline at end of file diff --git a/src/main/scala/lisa/settheory/SetTheoryZFAxioms.scala b/src/main/scala/lisa/settheory/SetTheoryZFAxioms.scala index 6ea73c22866260ea2152894f499ab443430498a9..d211beb2ce67cb0d060bdcb2b9dfe7e35258550e 100644 --- a/src/main/scala/lisa/settheory/SetTheoryZFAxioms.scala +++ b/src/main/scala/lisa/settheory/SetTheoryZFAxioms.scala @@ -11,9 +11,9 @@ private[settheory] trait SetTheoryZFAxioms extends SetTheoryZAxioms { forall(x, (in(x, a)) ==> existsOne(y, sPsi(a,x,y))) ==> exists(b, forall(x, in(x, a) ==> exists(y, in(y, b) /\ sPsi(a,x,y)))) ) - runningSetTheory.addAxiom(replacementSchema) + runningSetTheory.addAxiom("replacementSchema", replacementSchema) - override def axioms: Set[Axiom] = super.axioms + replacementSchema + override def axioms: Set[(String, Axiom)] = super.axioms + (("replacementSchema", replacementSchema)) } \ No newline at end of file diff --git a/src/main/scala/proven/DSetTheory/Part1.scala b/src/main/scala/proven/DSetTheory/Part1.scala index dbdd6a43583fcfe8a511190aaf2fbd9162133d6c..c3dd6d3c2265a3e8c0486605f4bb321aa1dc0ae5 100644 --- a/src/main/scala/proven/DSetTheory/Part1.scala +++ b/src/main/scala/proven/DSetTheory/Part1.scala @@ -16,7 +16,7 @@ import lisa.settheory.AxiomaticSetTheory import scala.collection.immutable object Part1 { val theory = AxiomaticSetTheory.runningSetTheory - def axiom(f:Formula) = theory.getAxioms.find(c => c.ax == f).get + def axiom(f:Formula):theory.Axiom = theory.getAxiom(f).get private val x = SchematicFunctionLabel("x", 0)() @@ -42,7 +42,7 @@ object Part1 { //val s4 = Rewrite(() |- !exists(y1, forall(x1, in(x1,y1) <=> !in(x1, x1))), 3) SCProof(s0, s1, s2) } - val thm_russelParadox = theory.proofToTheorem(russelParadox, Nil).get + val thm_russelParadox = theory.proofToTheorem("russelParadox", russelParadox, Nil).get val thm4:SCProof = { //forall(z, exists(y, forall(x, in(x,y) <=> (in(x,y) /\ sPhi(x,z))))) @@ -62,7 +62,7 @@ object Part1 { val s10 = Cut(forall(x1, in(x1, z)) |- (), 0, 9, exists(y1, forall(x1, in(x1,y1) <=> (in(x1,z) /\ !in(x1, x1)))) ) SCProof(Vector(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10), Vector(i1, i2)) } - val thm_thm4 = theory.proofToTheorem(thm4, Seq(axiom(comprehensionSchema), thm_russelParadox)).get + val thm_thm4 = theory.proofToTheorem("thm4", thm4, Seq(axiom(comprehensionSchema), thm_russelParadox)).get val thmMapFunctional: SCProof = { val a = VariableLabel("a") @@ -209,7 +209,7 @@ object Part1 { val steps = Vector(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22) SCProof(steps, Vector(i1, i2, i3)) } - val thm_thmMapFunctional = theory.proofToTheorem(thmMapFunctional, Seq(axiom(replacementSchema), axiom(comprehensionSchema),axiom(extensionalityAxiom))).get + val thm_thmMapFunctional = theory.proofToTheorem("thmMapFunctional", thmMapFunctional, Seq(axiom(replacementSchema), axiom(comprehensionSchema),axiom(extensionalityAxiom))).get /** * ∀ b. (b ∈ B) ⇒ ∀a. (a ∈ A) ⇒ ∃!x. ?psi(x, a, b) |- ∃!X. ∀x. (x ∈ X) ↔ ∃b. (b ∈ B) ∧ ∀x1. (x1 ∈ x) ↔ ∃a. (a ∈ A) ∧ ?psi(x1, a, b) @@ -251,7 +251,7 @@ object Part1 { // by thmMapFunctional have ∀b. (b ∈ B) ⇒ ∃!x. ∀x1. (x1 ∈ x) ↔ ∃a. (a ∈ A) ∧ ?psi(x1, a, b) ⊢ ∃!X. ∀x. (x ∈ X) ↔ ∃b. (b ∈ B) ∧ ∀x1. (x1 ∈ x) ↔ ∃a. (a ∈ A) ∧ ?psi(x1, a, b) phi(x, b) = ∀x1. (x1 ∈ x) ↔ ∃a. (a ∈ A) ∧ ?psi(x1, a, b) s6 // have ∀b. (b ∈ B) ⇒ ∀a. (a ∈ A) ⇒ ∃!x. ?psi(x, a, b) |- ∃!X. ∀x. (x ∈ X) ↔ ∃b. (b ∈ B) ∧ ∀x1. (x1 ∈ x) ↔ ∃a. (a ∈ A) ∧ ?psi(x1, a, b) s7 } - val thm_lemma1 = theory.proofToTheorem(lemma1, Seq(thm_thmMapFunctional)).get + val thm_lemma1 = theory.proofToTheorem("lemma1", lemma1, Seq(thm_thmMapFunctional)).get /* val lemma2 = SCProof({ @@ -326,7 +326,7 @@ object Part1 { // redGoal2 x=x1 <=> phi(x), z=F(x), x=x1 ⊢ F(x1)=z g2.s1 // redGoal2 x=x1 <=> phi(x), z=F(x1), x=x1 ⊢ F(x1)=z TRUE g2.s0 } - val thm_lemmaApplyFToObject = theory.proofToTheorem(lemmaApplyFToObject, Nil).get + val thm_lemmaApplyFToObject = theory.proofToTheorem("lemmaApplyFToObject", lemmaApplyFToObject, Nil).get /** * ∀b. (b ∈ ?B) ⇒ ∀a. (a ∈ ?A) ⇒ ∃!x. ?psi(x, a, b) ⊢ ∃!z. ∃x. (z = U(x)) ∧ ∀x_0. (x_0 ∈ x) ↔ ∃b. (b ∈ ?B) ∧ ∀x1. (x1 ∈ x_0) ↔ ∃a. (a ∈ ?A) ∧ ?psi(x1, a, b) @@ -353,7 +353,7 @@ object Part1 { val s2 = Cut(i1.left |- seq1.right, -1, 1, seq1.left.head) SCProof(Vector(s0,s1,s2), Vector(i1, i2)) } - val thm_lemmaMapTwoArguments = theory.proofToTheorem(lemmaMapTwoArguments, Seq(thm_lemma1, thm_lemmaApplyFToObject)).get + val thm_lemmaMapTwoArguments = theory.proofToTheorem("lemmaMapTwoArguments", lemmaMapTwoArguments, Seq(thm_lemma1, thm_lemmaApplyFToObject)).get /** * ⊢ ∃!z. ∃x. (z = U(x)) ∧ ∀x_0. (x_0 ∈ x) ↔ ∃b. (b ∈ ?B) ∧ ∀x1. (x1 ∈ x_0) ↔ ∃a. (a ∈ ?A) ∧ (x1 = (a, b)) @@ -394,7 +394,7 @@ object Part1 { } println("cartesian") - val thm_lemmaCartesianProduct = theory.proofToTheorem(lemmaCartesianProduct, Seq(thm_lemmaMapTwoArguments)).get + val thm_lemmaCartesianProduct = theory.proofToTheorem("lemmaCartesianProduct", lemmaCartesianProduct, Seq(thm_lemmaMapTwoArguments)).get val vA = VariableLabel("A") val vB = VariableLabel("B") diff --git a/src/main/scala/proven/ElementsOfSetTheory.scala b/src/main/scala/proven/ElementsOfSetTheory.scala index a103dbe012cb0c87d5bf4dfe44dc9027716c8009..36e7e30809d24659faef2a77df30f500ba398360 100644 --- a/src/main/scala/proven/ElementsOfSetTheory.scala +++ b/src/main/scala/proven/ElementsOfSetTheory.scala @@ -19,7 +19,7 @@ import scala.collection.immutable object ElementsOfSetTheory { val theory = AxiomaticSetTheory.runningSetTheory - def axiom(f:Formula) = theory.getAxioms.find(c => c.ax == f).get + def axiom(f:Formula): theory.Axiom = theory.getAxiom(f).get private val x = VariableLabel("x") private val y = VariableLabel("y") @@ -65,7 +65,7 @@ object ElementsOfSetTheory { val fin4 = generalizeToForall(fin3, fin3.conclusion.right.head, y) fin4.copy(imports = imps) } // |- ∀∀({x$1,y$2}={y$2,x$1}) - val thm_proofUnorderedPairSymmetry = theory.proofToTheorem(proofUnorderedPairSymmetry, Seq(axiom(extensionalityAxiom), axiom(pairAxiom))).get + val thm_proofUnorderedPairSymmetry = theory.proofToTheorem("proofUnorderedPairSymmetry", proofUnorderedPairSymmetry, Seq(axiom(extensionalityAxiom), axiom(pairAxiom))).get val proofUnorderedPairDeconstruction: SCProof = { @@ -223,13 +223,12 @@ object ElementsOfSetTheory { val p2 = RightImplies(emptySeq +> (p1.bot.left.head ==> p1.bot.right.head), 1, p1.bot.left.head, p1.bot.right.head) // |- ({x,y}={x',y'}) ==> (x=x' /\ y=y')\/(x=y' /\ y=x') generalizeToForall(SCProof(IndexedSeq(p0, p1, p2), IndexedSeq(()|-pairAxiom)), x, y, x1, y1) } // |- ∀∀∀∀(({x$4,y$3}={x'$2,y'$1})⇒(((y'$1=y$3)∧(x'$2=x$4))∨((x$4=y'$1)∧(y$3=x'$2)))) - val thm_proofUnorderedPairDeconstruction = theory.proofToTheorem(proofUnorderedPairDeconstruction, Seq(axiom(pairAxiom))).get + val thm_proofUnorderedPairDeconstruction = theory.proofToTheorem("proofUnorderedPairDeconstruction", proofUnorderedPairDeconstruction, Seq(axiom(pairAxiom))).get // i2, i1, p0, p1, p2, p3 val orderedPairDefinition: SCProof = simpleFunctionDefinition(pair(pair(x, y), pair(x, x)), Seq(x, y)) - println("def_oPair") val def_oPair = theory.makeFunctionDefinition(orderedPairDefinition, Nil, oPair, Seq(x, y), x1, x1 === pair(pair(x, y), pair(x, x))) /* diff --git a/src/test/scala/lisa/proven/SimpleProverTests.scala b/src/test/scala/lisa/proven/SimpleProverTests.scala index 5eb2269e58a8b82afeb609df11377f521cd7bf3e..3538752262928c4d671eb135a12f51ef2ec1242c 100644 --- a/src/test/scala/lisa/proven/SimpleProverTests.scala +++ b/src/test/scala/lisa/proven/SimpleProverTests.scala @@ -14,9 +14,9 @@ import proven.tactics.SimplePropositionalSolver as SPS class SimpleProverTests extends AnyFunSuite { + /* test("Simple propositional logic proofs") { val problems = getPRPproblems.take(1) - problems.foreach( pr => { println("--- Problem "+pr.file) val sq = problemToSequent(pr) @@ -29,4 +29,5 @@ class SimpleProverTests extends AnyFunSuite { }) } + */ }