
gapt.proofs.lkt.unfoldInduction.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gapt_3 Show documentation
Show all versions of gapt_3 Show documentation
General Architecture for Proof Theory
The newest version!
package gapt.proofs.lkt
import gapt.expr._
import gapt.expr.formula.Formula
import gapt.expr.subst.Substitution
import gapt.proofs.context.Context
import gapt.proofs.context.immutable.ImmutableContext
import gapt.proofs.lk.LKProofSubstitutableDefault
import gapt.provers.simp.{SimpEqResult, Simplifier}
trait SimpAdapter {
def hyps: Set[Hyp]
def simpEq(target: Expr): Option[(Bound1, Expr)]
}
case object NoopSimpAdapter extends SimpAdapter {
def hyps: Set[Hyp] = Set()
def simpEq(target: Expr): Option[(Bound1, Expr)] = None
}
case class SimplifierSimpAdapter(simp: Simplifier, lctx: LocalCtx) extends SimpAdapter {
def hyps = lctx.hyps.keySet.filter(_.inAnt)
def simpEq(target: Expr): Option[(Bound1, Expr)] = {
simp.simpEqToEql(target) match {
case SimpEqResult.Refl(_) => None
case SimpEqResult.Prf(lk, lhs, rhs) =>
val eqHyp = lctx.hyps.keySet.freshSuc
val lctx2 = lctx.updated(eqHyp, lhs === rhs)
val lkt = LKToLKt.forLCtx(lk, lctx2, debugging = true)
Some(Bound1(eqHyp, lkt), rhs)
}
}
}
class unfoldInduction(simp: SimpAdapter, ctx0: ImmutableContext) {
implicit val ctx: ImmutableContext = ctx0
var unfolded = false
val simpHyps = simp.hyps
def apply(b0: Bound1): Bound1 = {
val b = b0.rename_(simpHyps)
b.copy(p = apply(b.p))
}
def apply(b0: Bound2): Bound2 = {
val b = b0.rename_(simpHyps)
b.copy(p = apply(b.p))
}
def apply(b0: BoundN): BoundN = {
val b = b0.rename_(simpHyps)
b.copy(p = apply(b.p))
}
def apply(p: LKt): LKt = p match {
case Cut(f, q1, q2) => Cut(f, apply(q1), apply(q2))
case Ax(_, _) | Rfl(_) | TopR(_) | Link(_, _) => p
case NegR(main, q) => NegR(main, apply(q))
case NegL(main, q) => NegL(main, apply(q))
case AndR(main, q1, q2) => AndR(main, apply(q1), apply(q2))
case AndL(main, q) => AndL(main, apply(q))
case AllL(main, term, q) => AllL(main, term, apply(q))
case AllR(main, ev, q) => AllR(main, ev, apply(q))
case Eql(main, eq, ltr, rwCtx, q) => Eql(main, eq, ltr, rwCtx, apply(q))
case AllSk(main, term, q) => AllSk(main, term, apply(q))
case Def(main, f, q) => Def(main, f, apply(q))
case p @ Ind(main, f, term, cases0) =>
val cases = cases0.map(c => c.copy(q = c.q.rename_(simpHyps union p.freeHyps)))
val Some(ctrs) = ctx.getConstructors(p.indTy): @unchecked
assert(!simpHyps(main))
term match {
case Apps(ctr: Const, as) if ctrs.contains(ctr) =>
unfolded = true
// we need a proof of ⊢ main: φ(c(as))
val i = ctrs.indexOf(ctr)
val ci = cases(i)
var r = apply(Substitution(ci.evs zip as)(ci.q.p.replace(ci.q.auxs.head, main)))
for ((aux, recOcc) <- ci.q.auxs.tail.zip(as.filter(_.ty == p.indTy)))
r = Cut(
BetaReduction.betaNormalize(f(recOcc)).asInstanceOf[Formula],
Bound1(main, apply(Ind(main, f, recOcc, cases))),
Bound1(aux, r)
)
r
case _ =>
simp.simpEq(term) match {
case Some((simpPrf, newTerm)) =>
val eqHyp = (p.freeHyps union simpHyps).freshAnt
Cut(
term === newTerm,
simpPrf,
Bound1(
eqHyp,
Eql(main, eqHyp, ltr = true, f, Bound1(main, apply(Ind(main, f, newTerm, cases))))
)
)
case _ =>
Ind(main, f, term, cases.map(c => c.copy(q = apply(c.q))))
}
}
}
}
object unfoldInduction {
def apply(p: LKt)(implicit ctx: Context): Option[LKt] = apply(p, NoopSimpAdapter)
def apply(p: LKt, simp: SimpAdapter)(implicit ctx: Context): Option[LKt] = {
val ui = new unfoldInduction(simp, ctx.toImmutable)
val result = ui(p)
if (ui.unfolded) Some(result) else None
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy