diff --git a/build.sbt b/build.sbt index b63857e10c6ab502311a06054cf485a2cee8e468..a8d676f14d721174f4bf58a61d285a702c769b08 100644 --- a/build.sbt +++ b/build.sbt @@ -1,28 +1,25 @@ -inThisBuild( - Def.settings( - organization := "ch.epfl.lara", - organizationName := "LARA", - organizationHomepage := Some(url("https://lara.epfl.ch")), - licenses := Seq("Apache-2.0" -> url("https://www.apache.org/licenses/LICENSE-2.0.html")), - versionScheme := Some("semver-spec"), - scalacOptions ++= Seq( +ThisBuild / version := "0.6" +ThisBuild / homepage := Some(url("https://github.com/epfl-lara/lisa")) +ThisBuild / startYear := Some(2021) +ThisBuild / organization := "ch.epfl.lara" +ThisBuild / organizationName := "LARA" +ThisBuild / organizationHomepage := Some(url("https://lara.epfl.ch")) +ThisBuild / licenses := Seq("Apache-2.0" -> url("https://www.apache.org/licenses/LICENSE-2.0.html")) +ThisBuild / versionScheme := Some("semver-spec") +ThisBuild / scalacOptions ++= Seq( "-feature", "-deprecation", "-unchecked" - ), - javacOptions ++= Seq("-encoding", "UTF-8"), - semanticdbEnabled := true, - semanticdbVersion := scalafixSemanticdb.revision, - scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.6.0" - ) -) + ) +ThisBuild / javacOptions ++= Seq("-encoding", "UTF-8") +ThisBuild / semanticdbEnabled := true +ThisBuild / semanticdbVersion := scalafixSemanticdb.revision +ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.6.0" + val commonSettings = Seq( - version := "0.6", crossScalaVersions := Seq("2.12.13", "2.13.4", "3.0.1", "3.2.0"), - organization := "ch.epfl.lara", - scalacOptions ++= Seq("-Ximport-suggestion-timeout", "0"), run / fork := true ) @@ -30,13 +27,11 @@ val commonSettings = Seq( val scala2 = "2.13.8" val scala3 = "3.2.2" - - -val commonSettings2 = Seq( +val commonSettings2 = commonSettings ++ Seq( scalaVersion := scala2, scalacOptions ++= Seq("-Ypatmat-exhaust-depth", "50") ) -val commonSettings3 = Seq( +val commonSettings3 = commonSettings ++ Seq( scalaVersion := scala3, scalacOptions ++= Seq( "-language:implicitConversions", @@ -59,6 +54,7 @@ def githubProject(repo: String, commitHash: String) = RootProject(uri(s"$repo#$c lazy val scallion = githubProject("https://github.com/sankalpgambhir/scallion.git", "6434e21bd08872cf547c8f0efb67c963bfdf4190") lazy val silex = githubProject("https://github.com/epfl-lara/silex.git", "fc07a8670a5fa8ea2dd5649a00424710274a5d18") + scallion/scalacOptions ~= (_.filterNot(Set("-Wvalue-discard"))) silex/scalacOptions ~= (_.filterNot(Set("-Wvalue-discard"))) diff --git a/lisa-utils/src/main/scala/lisa/fol/Common.scala b/lisa-utils/src/main/scala/lisa/fol/Common.scala index deb0e55f6236db1e9f9c2fc16f794157cda8ec67..0e12da49bfc73f2d8dea3c45f0e743023d501fc2 100644 --- a/lisa-utils/src/main/scala/lisa/fol/Common.scala +++ b/lisa-utils/src/main/scala/lisa/fol/Common.scala @@ -49,15 +49,6 @@ trait Common { case l: Seq[T] => l.map(f).asInstanceOf[(U ** (N))] case tup: Tuple => tup.map[[t] =>> U]([u] => (x: u) => f(x.asInstanceOf[T])).asInstanceOf } - /* - object ** { - def unapply[T, N <: Arity](p: T**N): T***N = ValueOf[N] match { - case n: -1 => Some(p) - case n: 0 => if (p.size == 0) Some(EmptyTuple) else None - case n: _ => if (p.size == n) p match {case Tuple => p; case Seq} else None - } - } - */ } @@ -235,7 +226,6 @@ trait Common { def freshRename(taken: Iterable[Identifier]): TermLabel def mkString(args: Seq[Term]): String def mkStringSeparated(args: Seq[Term]): String = mkString(args) - // def unapply(t:Term):Option[Seq[Term]] } /** @@ -327,7 +317,6 @@ trait Common { override val underlyingLabel: K.VariableLabel = K.VariableLabel(id) override val underlying = K.VariableTerm(underlyingLabel) override def apply(args: Term ** 0) = this - def unapply(t: Variable): Option[Seq[Term]] = if (t == this) Some(Seq()) else None @nowarn("msg=Unreachable") override def substituteUnsafe(map: Map[SchematicLabel[_], LisaObject[_]]): Term = { map.get(this.asInstanceOf) match { @@ -358,7 +347,6 @@ trait Common { override val underlyingLabel: K.ConstantFunctionLabel = K.ConstantFunctionLabel(id, 0) override val underlying = K.Term(underlyingLabel, Seq()) override def apply(args: Term ** 0) = this - def unapply(t: Constant): Option[Term ** 0] = if (t == this) Some(Seq()) else None def substituteUnsafe(map: Map[SchematicLabel[_], LisaObject[_]]): Constant = this override def rename(newid: Identifier): Constant = Constant(newid) def freshRename(taken: Iterable[Identifier]): Constant = rename(K.freshId(taken, id)) @@ -375,7 +363,10 @@ trait Common { case class SchematicFunctionLabel[N <: Arity](val id: Identifier, val arity: N) extends SchematicTermLabel with SchematicLabel[(Term ** N) |-> Term] with ((Term ** N) |-> Term) { val underlyingLabel: K.SchematicTermLabel = K.SchematicFunctionLabel(id, arity) def apply(args: (Term ** N)): Term = AppliedTerm(this, args.toSeq) - def unapply(t: AppliedTerm): Option[Term ** N] = t match { case AppliedTerm(label, args) if (label == this) => Some(args); case _ => None } + def unapplySeq(t: AppliedTerm): Seq[Term] = t match { + case AppliedTerm(label, args) if (label == this) => args + case _ => Seq.empty + } @nowarn def substituteUnsafe(map: Map[SchematicLabel[_], LisaObject[_]]): ((Term ** N) |-> Term) = { map.get(this.asInstanceOf) match { @@ -403,7 +394,10 @@ trait Common { val underlyingLabel: K.ConstantFunctionLabel = K.ConstantFunctionLabel(id, arity) var infix: Boolean = false def apply(args: (Term ** N)): Term = AppliedTerm(this, args.toSeq) - def unapply(t: AppliedTerm): Option[Term ** N] = t match { case AppliedTerm(label, args) if (label == this) => Some(args); case _ => None } + def unapplySeq(t: AppliedTerm): Seq[Term] = t match { + case AppliedTerm(label, args) if (label == this) => args + case _ => Seq.empty + } inline def substituteUnsafe(map: Map[SchematicLabel[_], LisaObject[_]]): this.type = this def rename(newid: Identifier): ConstantFunctionLabel[N] = ConstantFunctionLabel(newid, arity) @@ -509,7 +503,6 @@ trait Common { val underlyingLabel: K.VariableFormulaLabel = K.VariableFormulaLabel(id) val underlying = K.PredicateFormula(underlyingLabel, Seq()) override def apply(args: Term ** 0): Formula = this - def unapply(t: VariableFormula): Option[Term ** 0] = if (t == this) Some(EmptyTuple) else None @nowarn("msg=Unreachable") def substituteUnsafe(map: Map[SchematicLabel[_], LisaObject[_]]): Formula = { map.get(this.asInstanceOf) match { @@ -539,7 +532,6 @@ trait Common { val underlyingLabel: K.ConstantPredicateLabel = K.ConstantPredicateLabel(id, 0) val underlying = K.PredicateFormula(underlyingLabel, Seq()) override def apply(args: Term ** 0): Formula = this - def unapply(t: ConstantFormula): Option[Term ** 0] = if (t == this) Some(EmptyTuple) else None def substituteUnsafe(map: Map[SchematicLabel[_], LisaObject[_]]): this.type = this def freeSchematicLabels: Set[SchematicLabel[?]] = Set.empty def allSchematicLabels: Set[SchematicLabel[?]] = Set.empty @@ -556,7 +548,10 @@ trait Common { case class SchematicPredicateLabel[N <: Arity](id: Identifier, arity: N) extends SchematicVarOrPredLabel with SchematicLabel[(Term ** N) |-> Formula] with ((Term ** N) |-> Formula) { val underlyingLabel: K.SchematicPredicateLabel = K.SchematicPredicateLabel(id, arity) def apply(args: (Term ** N)): Formula = PredicateFormula(this, args.toSeq) - def unapply(t: PredicateFormula): Option[Term ** N] = t match { case PredicateFormula(label, args) if (label == this) => Some(args); case _ => None } + def unapplySeq(t: AppliedTerm): Seq[Term] = t match { + case AppliedTerm(label, args) if (label == this) => args + case _ => Seq.empty + } @nowarn def substituteUnsafe(map: Map[SchematicLabel[_], LisaObject[_]]): |->[Term ** N, Formula] = { map.get(this.asInstanceOf) match { @@ -584,7 +579,10 @@ trait Common { val underlyingLabel: K.ConstantPredicateLabel = K.ConstantPredicateLabel(id, arity) private var infix = false def apply(args: (Term ** N)): Formula = PredicateFormula(this, args.toSeq) - def unapply(t: PredicateFormula): Option[Term ** N] = t match { case PredicateFormula(label, args) if (label == this) => Some(args); case _ => None } + def unapplySeq(f: PredicateFormula): Seq[Term] = f match { + case PredicateFormula(label, args) if (label == this) => args + case _ => Seq.empty + } def substituteUnsafe(map: Map[SchematicLabel[_], LisaObject[_]]): this.type = this def freeSchematicLabels: Set[SchematicLabel[?]] = Set.empty def allSchematicLabels: Set[SchematicLabel[?]] = Set.empty @@ -656,7 +654,10 @@ trait Common { } // def apply(args: Seq[Formula]): Formula = apply(args) def apply(args: Formula ** N): Formula = ConnectorFormula(this, args.toSeq) - def unapply(t: ConnectorFormula): Option[Seq[Formula]] = t match { case ConnectorFormula(label, args) if (label == this) => Some(args); case _ => None } + def unapplySeq(f: PredicateFormula): Seq[Term] = f match { + case PredicateFormula(label, args) if (label == this) => args + case _ => Seq.empty + } def freeSchematicLabels: Set[SchematicLabel[?]] = Set(this) def allSchematicLabels: Set[SchematicLabel[?]] = Set(this) def rename(newid: Identifier): SchematicConnectorLabel[N] = SchematicConnectorLabel(newid, arity) @@ -675,7 +676,10 @@ trait Common { def id: Identifier = underlyingLabel.id def substituteUnsafe(map: Map[SchematicLabel[_], LisaObject[_]]): this.type = this def apply(args: Formula ** N): Formula = ConnectorFormula(this, args.toSeq) - def unapply(t: ConnectorFormula): Option[Seq[Formula]] = t match { case ConnectorFormula(label, args) if (label == this) => Some(args); case _ => None } + def unapplySeq(f: ConnectorFormula): Seq[Formula] = f match { + case ConnectorFormula(label, args) if (label == this) => args + case _ => Seq.empty + } def freeSchematicLabels: Set[SchematicLabel[?]] = Set.empty def allSchematicLabels: Set[SchematicLabel[?]] = Set.empty def rename(newid: Identifier): ConstantConnectorLabel[N] = throw new Error("Can't rename a constant connector label") diff --git a/lisa-utils/src/main/scala/lisa/fol/FOLHelpers.scala b/lisa-utils/src/main/scala/lisa/fol/FOLHelpers.scala index 30002495f67947749f44d1ee459bd46415986818..e4039adf9f798e4b3c2e9b74b61baab86a1a9412 100644 --- a/lisa-utils/src/main/scala/lisa/fol/FOLHelpers.scala +++ b/lisa-utils/src/main/scala/lisa/fol/FOLHelpers.scala @@ -65,7 +65,7 @@ object FOLHelpers { case n: 0 => Constant(cfl.id) case n: N => ConstantFunctionLabel[N](cfl.id, n) def asFrontLabel(stl: K.SchematicTermLabel): SchematicTermLabel = stl match - case v: K.VariableLabel => asFrontLabel(stl) + case v: K.VariableLabel => asFrontLabel(v) case v: K.SchematicFunctionLabel => asFrontLabel(v) def asFrontLabel[N <: Arity](sfl: K.SchematicFunctionLabel): SchematicFunctionLabel[N] = SchematicFunctionLabel(sfl.id, sfl.arity.asInstanceOf) diff --git a/lisa-utils/src/main/scala/lisa/fol/Sequents.scala b/lisa-utils/src/main/scala/lisa/fol/Sequents.scala index e2bbd1c0d9bd74b8809f74f721e8d3135d79cb20..31c62f3c40029626c4745bea61cba5e90944eee8 100644 --- a/lisa-utils/src/main/scala/lisa/fol/Sequents.scala +++ b/lisa-utils/src/main/scala/lisa/fol/Sequents.scala @@ -146,7 +146,10 @@ trait Sequents extends Common with lisa.fol.Lambdas { infix def --?(s1: Sequent): Sequent = this removeAll s1 infix def ++?(s1: Sequent): Sequent = this addAllIfNotExists s1 - override def toString = left.mkString("; ") + " ⊢ " + right.mkString("; ") + override def toString = + (if left.size == 1 then left.head.toString else "( " + left.mkString(", ") + " )") + + " ⊢ " + + (if right.size == 1 then right.head.toString else "( " + right.mkString(", ") + " )") } diff --git a/lisa-utils/src/main/scala/lisa/prooflib/BasicStepTactic.scala b/lisa-utils/src/main/scala/lisa/prooflib/BasicStepTactic.scala index 8d066ea2a4a14a14549ddbe1209e7b08b53ec433..80f40640caa88e7b4e6322e3bb517ff961da7a8e 100644 --- a/lisa-utils/src/main/scala/lisa/prooflib/BasicStepTactic.scala +++ b/lisa-utils/src/main/scala/lisa/prooflib/BasicStepTactic.scala @@ -1354,25 +1354,34 @@ object BasicStepTactic { proof.ValidProofTactic(res, Seq(K.InstSchema(botK, -1, mConK, mPredK, mTermK)), Seq(premise)) } } + object Subproof extends ProofTactic { + def apply(using proof: Library#Proof)(statement: Option[F.Sequent])(iProof: proof.InnerProof) = { + val bot: Option[F.Sequent] = statement + val botK: Option[K.Sequent] = statement map (_.underlying) + if (iProof.length == 0) throw (new UnimplementedProof(proof.owningTheorem)) + val scproof: K.SCProof = iProof.toSCProof + val premises: Seq[proof.Fact] = iProof.getImports.map(of => of._1) + val judgement: proof.ProofTacticJudgement = { + if (botK.isEmpty) + proof.ValidProofTactic(iProof.mostRecentStep.bot, scproof.steps, premises) + else if (!K.isSameSequent(botK.get, scproof.conclusion)) + proof.InvalidProofTactic( + s"The subproof does not prove the desired conclusion.\n\tExpected: ${FOLPrinter.prettySequent(botK.get)}\n\tObtained: ${FOLPrinter.prettySequent(scproof.conclusion)}" + ) + else + proof.ValidProofTactic(bot.get, scproof.steps :+ K.Restate(botK.get, scproof.length - 1), premises) + } + judgement + } + } - class SUBPROOF(using val proof: Library#Proof)(statement: Option[F.Sequent])(computeProof: proof.InnerProof ?=> Unit) extends ProofTactic { + class SUBPROOF(using val proof: Library#Proof)(statement: Option[F.Sequent])(val iProof: proof.InnerProof) extends ProofTactic { val bot: Option[F.Sequent] = statement val botK: Option[K.Sequent] = statement map (_.underlying) + if (iProof.length == 0) + throw (new UnimplementedProof(proof.owningTheorem)) + val scproof: K.SCProof = iProof.toSCProof - val iProof: proof.InnerProof = new proof.InnerProof(statement.asInstanceOf) - val scproof: K.SCProof = { - try { - computeProof(using iProof) - } catch { - case e: NotImplementedError => - throw (new UnimplementedProof(proof.owningTheorem)) - case e: UserLisaException => - throw (e) - } - if (iProof.length == 0) - throw (new UnimplementedProof(proof.owningTheorem)) - iProof.toSCProof - } val premises: Seq[proof.Fact] = iProof.getImports.map(of => of._1) def judgement: proof.ProofTacticJudgement = { if (botK.isEmpty) @@ -1384,20 +1393,17 @@ object BasicStepTactic { } } + // TODO make specific support for subproofs written inside tactics. + + inline def TacticSubproof(using proof: Library#Proof)(inline computeProof: proof.InnerProof ?=> Unit): proof.ProofTacticJudgement = + val iProof: proof.InnerProof = new proof.InnerProof(None) + computeProof(using iProof) + SUBPROOF(using proof)(None)(iProof).judgement.asInstanceOf[proof.ProofTacticJudgement] + object Sorry extends ProofTactic with ProofSequentTactic { def apply(using lib: Library, proof: lib.Proof)(bot: F.Sequent): proof.ProofTacticJudgement = { proof.ValidProofTactic(bot, Seq(K.Sorry(bot.underlying)), Seq()) } } - // TODO make specific support for subproofs written inside tactics. - - def TacticSubproof(using proof: Library#Proof)(computeProof: proof.InnerProof ?=> Unit) = - SUBPROOF(using proof)(None)(computeProof).judgement.asInstanceOf[proof.ProofTacticJudgement] - - /* - def TacticSubproof(using proof: Library#Proof)(botK: Option[Sequent])(computeProof: proof.InnerProof ?=> Unit) = - SUBPROOF(using proof)(Some(botK))(computeProof).judgement.asInstanceOf[proof.ProofTacticJudgement] - */ - } diff --git a/lisa-utils/src/main/scala/lisa/prooflib/ProofsHelpers.scala b/lisa-utils/src/main/scala/lisa/prooflib/ProofsHelpers.scala index 037cbf302a5c850c721d2895d396051a48b24bb6..5fe1901e905d8b75b42e3645aac0a36519aea82f 100644 --- a/lisa-utils/src/main/scala/lisa/prooflib/ProofsHelpers.scala +++ b/lisa-utils/src/main/scala/lisa/prooflib/ProofsHelpers.scala @@ -35,9 +35,11 @@ trait ProofsHelpers { } } - inline infix def subproof(using proof: Library#Proof, om: OutputManager, line: sourcecode.Line, file: sourcecode.File)(tactic: proof.InnerProof ?=> Unit): proof.ProofStep = { + infix def subproof(using proof: Library#Proof, om: OutputManager, line: sourcecode.Line, file: sourcecode.File)(computeProof: proof.InnerProof ?=> Unit): proof.ProofStep = { val botWithAssumptions = HaveSequent.this.bot ++ (proof.getAssumptions |- ()) - (new BasicStepTactic.SUBPROOF(using proof)(Some(botWithAssumptions))(tactic)).judgement.validate(line, file).asInstanceOf[proof.ProofStep] + val iProof: proof.InnerProof = new proof.InnerProof(Some(botWithAssumptions)) + computeProof(using iProof) + (new BasicStepTactic.SUBPROOF(using proof)(Some(botWithAssumptions))(iProof)).judgement.validate(line, file).asInstanceOf[proof.ProofStep] } } @@ -176,6 +178,9 @@ trait ProofsHelpers { val f: F.Formula, j: JUSTIFICATION ) extends DEFINITION(line, file) { + def repr: String = + s" ${if (withSorry) " Sorry" else ""} Definition of function symbol ${label(vars)} := the ${out} such that ${(out === label(vars)) <=> f})\n" + // val expr = LambdaExpression[Term, Formula, N](vars, f, valueOf[N]) lazy val label: ConstantFunctionLabelOfArity[N] = (if (vars.length == 0) F.Constant(name) else F.ConstantFunctionLabel[N](name, vars.length.asInstanceOf)).asInstanceOf @@ -188,8 +193,8 @@ trait ProofsHelpers { UserInvalidDefinitionException( name, s"The given justification is not valid for a definition" + - s"The justification should be of the form ${FOLPrinter.prettySequent((() |- F.BinderFormula(F.ExistsOne, out, F.VariableFormula("phi"))).underlying)}" + - s"instead of the given ${FOLPrinter.prettySequent(conclusion.underlying)}" + s"The justification should be of the form ${(() |- F.BinderFormula(F.ExistsOne, out, F.VariableFormula("phi")))}" + + s"instead of the given ${conclusion.underlying}" ) ) } @@ -211,8 +216,8 @@ trait ProofsHelpers { UserInvalidDefinitionException( name, s"The given justification is not valid for a definition" + - s"The justification should be of the form ${FOLPrinter.prettySequent((() |- F.BinderFormula(F.ExistsOne, out, F.VariableFormula("phi"))).underlying)}" + - s"instead of the given ${FOLPrinter.prettySequent(conclusion.underlying)}" + s"The justification should be of the form ${(() |- F.BinderFormula(F.ExistsOne, out, F.VariableFormula("phi")))}" + + s"instead of the given ${conclusion.underlying}" ) ) } @@ -283,7 +288,11 @@ trait ProofsHelpers { val lambda: LambdaExpression[Term, Term, N], out: F.Variable, j: JUSTIFICATION - ) extends FunctionDefinition[N](name, fullName, line, file)(lambda.bounds.asInstanceOf, out, out === lambda.body, j) {} + ) extends FunctionDefinition[N](name, fullName, line, file)(lambda.bounds.asInstanceOf, out, out === lambda.body, j) { + override def repr: String = + s" Definition of function symbol ${label(lambda.bounds.asInstanceOf)} := ${lambda.body}${if (j.withSorry) " (!! Relies on Sorry)" else ""}\n" + + } object SimpleFunctionDefinition { def apply[N <: F.Arity](using om: OutputManager)(name: String, fullName: String, line: Int, file: String)(lambda: LambdaExpression[Term, Term, N]): SimpleFunctionDefinition[N] = { @@ -300,7 +309,8 @@ trait ProofsHelpers { class PredicateDefinition[N <: F.Arity](using om: OutputManager)(name: String, fullName: String, line: Int, file: String)(val lambda: LambdaExpression[Term, Formula, N]) extends DEFINITION(line, file) { - + override def repr: String = + s" Definition of predicate symbol ${label(lambda.bounds.asInstanceOf)} := ${lambda.body}" lazy val vars: Seq[F.Variable] = lambda.bounds.asInstanceOf val arity = lambda.arity diff --git a/lisa-utils/src/main/scala/lisa/prooflib/SimpleDeducedSteps.scala b/lisa-utils/src/main/scala/lisa/prooflib/SimpleDeducedSteps.scala index 0c8ee41f065852f2c7365e9a50a29bcc8ea75609..8e470c1436be3327df813d8d5a38a317e1ada3e3 100644 --- a/lisa-utils/src/main/scala/lisa/prooflib/SimpleDeducedSteps.scala +++ b/lisa-utils/src/main/scala/lisa/prooflib/SimpleDeducedSteps.scala @@ -160,12 +160,12 @@ object SimpleDeducedSteps { def apply(using lib: Library, proof: lib.Proof)(bot: F.Sequent): proof.ProofTacticJudgement = { try { - val sp = new BasicStepTactic.SUBPROOF(using proof)(Some(bot))({ + val sp = TacticSubproof { // lazy val premiseSequent = proof.getSequent(premise) - val s1 = proof.library.have(bot +<< bot.right.head) by Restate - proof.library.have(bot) by LeftForall(s1) - }) - BasicStepTactic.unwrapTactic(sp.judgement.asInstanceOf[proof.ProofTacticJudgement])("Subproof substitution fail.") + val s1 = lib.have(bot +<< bot.right.head) by Restate + lib.have(bot) by LeftForall(s1) + } + BasicStepTactic.unwrapTactic(sp)("Subproof substitution fail.") } catch { case e: Exception => proof.InvalidProofTactic("Impossible to justify desired step with instantiation.") } diff --git a/lisa-utils/src/main/scala/lisa/prooflib/Substitution.scala b/lisa-utils/src/main/scala/lisa/prooflib/Substitution.scala index 584bb3b212f458353f690d16d591491102791fa4..b5e720b7b50a19a8807c6dfec096526c0e0a4d4a 100644 --- a/lisa-utils/src/main/scala/lisa/prooflib/Substitution.scala +++ b/lisa-utils/src/main/scala/lisa/prooflib/Substitution.scala @@ -21,13 +21,13 @@ import F.|- object Substitution { def validRule(using lib: lisa.prooflib.Library, proof: lib.Proof)(r: (proof.Fact | F.Formula | lib.JUSTIFICATION)): Boolean = r match { - case F.equality(_) => true - case F.Iff(_) => true + case F.equality(_, _) => true + case F.Iff(_, _) => true + case _: Formula => false case j: lib.JUSTIFICATION => j.statement.right.size == 1 && validRule(j.statement.right.head) case f: proof.Fact @unchecked => proof.sequentOfFact(f).right.size == 1 && validRule(proof.sequentOfFact(f).right.head) // case j: RunningTheory#Justification => // proof.sequentOfFact(j.asInstanceOf[lib.theory.Justification]).right.size == 1 && validRule(proof.sequentOfFact(j.asInstanceOf[lib.theory.Justification]).right.head) - case _ => false } object ApplyRules extends ProofTactic { @@ -565,13 +565,13 @@ object Substitution { case f: proof.Fact => val seq = proof.getSequent(f) val phi = seq.right.head - val sp = new BasicStepTactic.SUBPROOF(using proof)(None)({ + val sp = TacticSubproof { val x = applyLeftRight(phi)(premise)(rightLeft, toLeft, toRight) proof.library.have(x) proof.library.andThen(SimpleDeducedSteps.Discharge(f)) - }) + } - BasicStepTactic.unwrapTactic(sp.judgement.asInstanceOf[proof.ProofTacticJudgement])("Subproof substitution fail.") + BasicStepTactic.unwrapTactic(sp)("Subproof substitution fail.") } } diff --git a/lisa-utils/src/main/scala/lisa/prooflib/WithTheorems.scala b/lisa-utils/src/main/scala/lisa/prooflib/WithTheorems.scala index 7b27153f60d16bbcb32af8948de9f75ad3848215..27a9aa6877d158226222afbc7cec71646bd96c86 100644 --- a/lisa-utils/src/main/scala/lisa/prooflib/WithTheorems.scala +++ b/lisa-utils/src/main/scala/lisa/prooflib/WithTheorems.scala @@ -289,7 +289,7 @@ trait WithTheorems { if (statement.underlying != theory.sequentFromJustification(innerAxiom)) { throw new InvalidAxiomException("The provided kernel axiom and desired statement don't match.", name, axiom, library) } - def repr: String = innerJustification.repr + def repr: String = s" Axiom $name := $axiom" } def Axiom(name: String, axiom: F.Formula): AXIOM = { @@ -302,7 +302,7 @@ trait WithTheorems { // def Axiom(using om: OutputManager, line: Int, file: String)(ax: theory.Axiom): AXIOM = AXIOM(line, file, ax.) abstract class DEFINITION(line: Int, file: String) extends JUSTIFICATION { - def repr: String = innerJustification.repr + def label: F.ConstantLabel[?] knownDefs.update(label, Some(this)) @@ -318,7 +318,7 @@ trait WithTheorems { val innerJustification: theory.Theorem = prove(computeProof) def prettyGoal: String = lisa.utils.FOLPrinter.prettySequent(goal.underlying) - def repr: String = innerJustification.repr + def repr: String = s" ${if (withSorry) " Sorry" else ""} Theorem $name := $statement\n" private def prove(computeProof: Proof ?=> Unit): theory.Theorem = { try { diff --git a/src/main/scala/lisa/automation/settheory/SetTheoryTactics.scala b/src/main/scala/lisa/automation/settheory/SetTheoryTactics.scala index f1dc59402eccc2edf0d0e58c96e1ac097cbb14d9..3e3264e7f6e19bb5e630c2d494d1aeff696312d7 100644 --- a/src/main/scala/lisa/automation/settheory/SetTheoryTactics.scala +++ b/src/main/scala/lisa/automation/settheory/SetTheoryTactics.scala @@ -71,7 +71,7 @@ object SetTheoryTactics { * import ∃ z. t ∈ z <=> (t ∈ x /\ P(t, x)) |- ∃! z. t ∈ z <=> (t ∈ x /\ P(t, x)) Unique by Extension [[uniqueByExtension]] Instantiation * have () |- ∃! z. t ∈ z <=> (t ∈ x /\ P(t, x)) Cut */ - val sp = SUBPROOF(using proof)(Some(botWithAssumptions)) { // TODO check if isInstanceOf first + val sp = TacticSubproof { // TODO check if isInstanceOf first val existence = have(() |- exists(t1, fprop(t1))) by Weakening(comprehensionSchema of (z -> originalSet, φ -> separationPredicate)) val existsToUnique = have(exists(t1, fprop(t1)) |- existsOne(t1, fprop(t1))) by Weakening(SetTheory.uniqueByExtension of schemPred -> lambda(t2, prop)) @@ -81,7 +81,7 @@ object SetTheoryTactics { } // safely check, unwrap, and return the proof judgement - unwrapTactic(sp.judgement.asInstanceOf[proof.ProofTacticJudgement])("Subproof for unique comprehension failed.") + unwrapTactic(sp)("Subproof for unique comprehension failed.") } }