gapt.proofs.lkt.makeEqualityExplicit.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.formula.All
import gapt.expr.formula.Eq
import gapt.expr.formula.Formula
import gapt.expr.ty.Ty
import gapt.expr.util.freeVariables
import gapt.expr.util.rename
import gapt.expr.{BetaReduction, Expr, Var, ExprNameGenerator}
import scala.collection.mutable
class makeEqualityExplicit(debugging: Boolean) extends FreshHyp {
// (replacement context, ltr) |-> (hyp, eqAxiom)
val rwrHyps = mutable.Map[(Expr, Boolean), (Hyp, Formula)]()
// ty |-> (hyp, rflAxiom)
val reflHyps = mutable.Map[Ty, (Hyp, Formula)]()
def effectiveLCtx(lctx: LocalCtx): LocalCtx =
lctx.updated(rwrHyps.values).updated(reflHyps.values)
def apply(p: LKt, lctx: LocalCtx): (LKt, LocalCtx) = {
markUsed(p)
val q = go(p, lctx)
q -> effectiveLCtx(lctx)
}
def go(b: Bound1, lctx: LocalCtx): Bound1 = b.copy(p = go(b.p, lctx))
def go(b: Bound2, lctx: LocalCtx): Bound2 = b.copy(p = go(b.p, lctx))
def go(b: BoundN, lctx: LocalCtx): BoundN = b.copy(p = go(b.p, lctx))
def go(p: LKt, lctx: LocalCtx): LKt = {
val result = p match {
case Cut(f, q1, q2) => Cut(f, go(q1, lctx.up1(p)), go(q2, lctx.up2(p)))
case Ax(_, _) | TopR(_) | Link(_, _) => p
case Rfl(main) =>
val Eq(t, _) = lctx(main): @unchecked
val rflHyp = reflHyps.getOrElseUpdate(
t.ty, {
val x = Var("x", t.ty)
(freshAnt(), All(x, x === x))
}
)._1
AllL(rflHyp, t, Bound1(rflHyp, Ax(rflHyp, main)))
case NegR(main, q) => NegR(main, go(q, lctx.up1(p)))
case NegL(main, q) => NegL(main, go(q, lctx.up1(p)))
case AndR(main, q1, q2) => AndR(main, go(q1, lctx.up1(p)), go(q2, lctx.up2(p)))
case AndL(main, q) => AndL(main, go(q, lctx.up1(p)))
case AllL(main, term, q) => AllL(main, term, go(q, lctx.up1(p)))
case AllR(main, ev, q) => AllR(main, ev, go(q, lctx.up1(p)))
case Eql(main, eq, ltr, rwCtx, q) =>
val Eq(l, r) = lctx(eq): @unchecked
val extraVars = freeVariables(rwCtx).toList
val effLtr = ltr == main.inAnt
val rwrHyp = rwrHyps.getOrElseUpdate(
(rwCtx, effLtr), {
val nameGen = rename.awayFrom(extraVars)
val x = nameGen.fresh(Var("x", l.ty))
val y = nameGen.fresh(Var("y", l.ty))
val ax = All.Block(
extraVars :+ x :+ y,
(x === y) --> BetaReduction.betaNormalize(
if (effLtr) rwCtx(x) --> rwCtx(y) else rwCtx(y) --> rwCtx(x)
)
)
(freshAnt(), ax)
}
)._1
val aux = freshSuc()
AllLBlock(
rwrHyp,
extraVars :+ l :+ r,
Bound1(
rwrHyp,
AndR(
rwrHyp,
Bound1(aux, Ax(eq, aux)),
Bound1(
rwrHyp,
AndR(
rwrHyp,
Bound1(aux, if (main.inAnt) Ax(main, aux) else go(q, lctx.up1(p)).inst(aux)),
Bound1(rwrHyp, if (main.inSuc) Ax(rwrHyp, main) else go(q, lctx.up1(p)).inst(rwrHyp))
)
)
)
)
)
case AllSk(main, term, q) => AllSk(main, term, go(q, lctx.up1(p)))
case Def(main, f, q) => Def(main, f, go(q, lctx.up1(p)))
case Ind(main, f, term, cases) =>
Ind(main, f, term, cases.zipWithIndex.map { case (c, i) => c.copy(q = go(c.q, lctx.upn(p, i))) })
}
if (debugging) check(result, effectiveLCtx(lctx))
result
}
}
object makeEqualityExplicit {
def apply(p: LKt, lctx: LocalCtx, debugging: Boolean = false): (LKt, LocalCtx) =
new makeEqualityExplicit(debugging).apply(p, lctx)
}