All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gapt.proofs.lkt.atomizeEquality.scala Maven / Gradle / Ivy

package gapt.proofs.lkt

import gapt.expr._
import gapt.expr.formula.All
import gapt.expr.formula.And
import gapt.expr.formula.Atom
import gapt.expr.formula.Ex
import gapt.expr.formula.Imp
import gapt.expr.formula.Neg
import gapt.expr.formula.Or
import gapt.expr.util.freeVariables
import gapt.proofs.lk.LKProof

object atomizeEquality {

  def apply(b: Bound1, lctx: LocalCtx): Bound1 = b.copy(p = apply(b.p, lctx))
  def apply(b: Bound2, lctx: LocalCtx): Bound2 = b.copy(p = apply(b.p, lctx))
  def apply(b: BoundN, lctx: LocalCtx): BoundN = b.copy(p = apply(b.p, lctx))

  def apply(p: LKProof): LKProof = {
    val (q, lctx) = LKToLKt(p)
    LKtToLK(apply(q, lctx), lctx)
  }

  def apply(p: LKt, lctx: LocalCtx): LKt = p match {
    case Cut(f, q1, q2) =>
      Cut(f, apply(q1, lctx.up1(p)), apply(q2, lctx.up2(p)))
    case Ax(_, _) | Rfl(_) | TopR(_) | Link(_, _) => p
    case NegR(main, q) =>
      NegR(main, apply(q, lctx.up1(p)))
    case NegL(main, q) =>
      NegL(main, apply(q, lctx.up1(p)))
    case AndR(main, q1, q2) =>
      AndR(main, apply(q1, lctx.up1(p)), apply(q2, lctx.up2(p)))
    case AndL(main, q) =>
      AndL(main, apply(q, lctx.up1(p)))
    case AllL(main, term, q) =>
      AllL(main, term, apply(q, lctx.up1(p)))
    case AllR(main, ev, q) =>
      AllR(main, ev, apply(q, lctx.up1(p)))
    case Eql(main, eq, ltr, rwCtx @ Abs(_, _: Atom), q) =>
      Eql(main, eq, ltr, rwCtx, apply(q, lctx.up1(p)))
    case Eql(main, eq, ltr, rwCtx, q) =>
      if (main.inAnt) {
        val aux = Set(main, eq).fresh(!main.polarity)
        val cutf = lctx.up1(p)(q.aux)
        val sim = simulate(rwCtx, ltr, eq, main, aux)
        Cut(cutf, Bound1(aux, sim), apply(q, lctx.up1(p)))
      } else {
        val aux = Set(main, eq).fresh(!main.polarity)
        val cutf = lctx.up1(p)(q.aux)
        val sim = simulate(rwCtx, !ltr, eq, aux, main)
        Cut(cutf, apply(q, lctx.up1(p)), Bound1(aux, sim))
      }
    case AllSk(main, term, q) =>
      AllSk(main, term, apply(q, lctx.up1(p)))
    case Def(main, f, q) =>
      Def(main, f, apply(q, lctx.up1(p)))
    case Ind(main, f, term, cases) =>
      Ind(main, f, term, cases.zipWithIndex.map { case (c, i) => c.copy(q = apply(c.q, lctx.upn(p, i))) })
  }

  /**
   * Produces a proof of
   * eq: l=r, left: rwCtx(l) :- right: rwCtx(r)
   */
  def simulate(rwCtx: Expr, ltr: Boolean, eq: Hyp, left: Hyp, right: Hyp): LKt =
    rwCtx match {
      case Abs(x, phi) if !freeVariables(phi).contains(x) =>
        Ax(left, right)
      case Abs(x, Neg(phi)) =>
        val List(left_, right_) =
          Set(eq, left, right).freshSameSide(List(left, right))
        NegL(
          left,
          Bound1(
            right_,
            NegR(
              right,
              Bound1(
                left_,
                simulate(Abs(x, phi), !ltr, eq, left_, right_)
              )
            )
          )
        )
      case Abs(x, And(phi, psi)) =>
        val List(left1, left2, right1, right2) =
          Set(eq, left, right).freshSameSide(List(left, left, right, right))
        AndL(
          left,
          Bound2(
            left1,
            left2,
            AndR(
              right,
              Bound1(right1, simulate(Abs(x, phi), ltr, eq, left1, right1)),
              Bound1(right2, simulate(Abs(x, psi), ltr, eq, left2, right2))
            )
          )
        )
      case Abs(x, Or(phi, psi)) =>
        val List(left1, left2, right1, right2) =
          Set(eq, left, right).freshSameSide(List(left, left, right, right))
        AndL(
          right,
          Bound2(
            right1,
            right2,
            AndR(
              left,
              Bound1(left1, simulate(Abs(x, phi), ltr, eq, left1, right1)),
              Bound1(left2, simulate(Abs(x, psi), ltr, eq, left2, right2))
            )
          )
        )
      case Abs(x, Imp(phi, psi)) =>
        val List(left1, left2, right1, right2) =
          Set(eq, left, right).freshSameSide(List(left, left, right, right))
        AndL(
          right,
          Bound2(
            left1,
            right2,
            AndR(
              left,
              Bound1(right1, simulate(Abs(x, phi), !ltr, eq, left1, right1)),
              Bound1(left2, simulate(Abs(x, psi), ltr, eq, left2, right2))
            )
          )
        )
      case Abs(x, All(y, phi)) =>
        assert(x != y)
        val List(left_, right_) =
          Set(eq, left, right).freshSameSide(List(left, right))
        AllR(
          right,
          y,
          Bound1(
            right_,
            AllL(
              left,
              y,
              Bound1(
                left_,
                simulate(Abs(x, phi), ltr, eq, left_, right_)
              )
            )
          )
        )
      case Abs(x, Ex(y, phi)) =>
        assert(x != y)
        val List(left_, right_) =
          Set(eq, left, right).freshSameSide(List(left, right))
        AllR(
          left,
          y,
          Bound1(
            left_,
            AllL(
              right,
              y,
              Bound1(
                right_,
                simulate(Abs(x, phi), ltr, eq, left_, right_)
              )
            )
          )
        )
      case _ =>
        Eql(left, eq, ltr, rwCtx, Bound1(left, Ax(left, right)))
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy