From f0b6101d90121776711f02eb956155d3674201ab Mon Sep 17 00:00:00 2001
From: Katja Goltsova <katja.goltsova@protonmail.com>
Date: Mon, 3 Oct 2022 18:24:05 +0200
Subject: [PATCH] Use scallion-based printer to pretty print proofs

---
 .../src/main/scala/lisa/utils/Printer.scala   | 174 +-----------------
 1 file changed, 3 insertions(+), 171 deletions(-)

diff --git a/lisa-utils/src/main/scala/lisa/utils/Printer.scala b/lisa-utils/src/main/scala/lisa/utils/Printer.scala
index f6e3c259..75c5837e 100644
--- a/lisa-utils/src/main/scala/lisa/utils/Printer.scala
+++ b/lisa-utils/src/main/scala/lisa/utils/Printer.scala
@@ -15,116 +15,6 @@ object Printer {
 
   private def commaSeparator(compact: Boolean, symbol: String = ","): String = s"$symbol${spaceSeparator(compact)}"
 
-  private def prettyParentheses(content: String): String = s"(${content})"
-
-  private def prettyFunction(name: String, args: Seq[String], compact: Boolean, dropParentheses: Boolean = true): String = {
-    if (dropParentheses && args.isEmpty) name else s"$name(${args.mkString(commaSeparator(compact))})"
-  }
-
-  private def prettyInfix(operator: String, left: String, right: String, compact: Boolean): String =
-    Seq(left, operator, right).mkString(spaceSeparator(compact))
-
-  // Special symbols that aren't defined in this theory
-  private val (membership, subsetOf, sameCardinality) = (
-    ConstantPredicateLabel("set_membership", 2),
-    ConstantPredicateLabel("subset_of", 2),
-    ConstantPredicateLabel("same_cardinality", 2)
-  )
-  private val (emptySet, unorderedPair, orderedPair, singleton, powerSet, unionSet) = (
-    ConstantFunctionLabel("empty_set", 0),
-    ConstantFunctionLabel("unordered_pair", 2),
-    ConstantFunctionLabel("ordered_pair", 2),
-    ConstantFunctionLabel("singleton", 1),
-    ConstantFunctionLabel("power_set", 1),
-    ConstantFunctionLabel("union", 1)
-  )
-
-  private val nonAtomicPredicates: Set[PredicateLabel] = Set(equality, membership, subsetOf, sameCardinality) // Predicates which require parentheses (for readability)
-
-  private def prettyFormulaInternal(formula: Formula, isRightMost: Boolean, compact: Boolean): String = formula match {
-    case PredicateFormula(label, args) =>
-      label match {
-        case `equality` =>
-          args match {
-            case Seq(l, r) => prettyInfix(label.id, prettyTerm(l), prettyTerm(r), compact)
-            case _ => throw new Exception
-          }
-        case `membership` =>
-          args match {
-            case Seq(l, r) => prettyInfix("∈", prettyTerm(l), prettyTerm(r), compact)
-            case _ => throw new Exception
-          }
-        case `subsetOf` =>
-          args match {
-            case Seq(l, r) => prettyInfix("⊆", prettyTerm(l), prettyTerm(r), compact)
-            case _ => throw new Exception
-          }
-        case `sameCardinality` =>
-          args match {
-            case Seq(l, r) => prettyInfix("~", prettyTerm(l), prettyTerm(r), compact)
-            case _ => throw new Exception
-          }
-        case _ =>
-          val labelString = label match {
-            case ConstantPredicateLabel(id, _) => id
-            case s: SchematicPredicateLabel => s"?${s.id}"
-          }
-          prettyFunction(labelString, args.map(prettyTerm(_, compact)), compact)
-      }
-    case ConnectorFormula(label, args) =>
-      (label, args) match {
-        case (Neg, Seq(arg)) =>
-          val isAtomic = arg match {
-            case PredicateFormula(label, _) => !nonAtomicPredicates.contains(label)
-            case ConnectorFormula(Neg, _) => true
-            case _ => false
-          }
-          val bodyString = prettyFormulaInternal(arg, isRightMost, compact)
-          val bodyParenthesized = if (isAtomic) bodyString else prettyParentheses(bodyString)
-          s"${label.id}${bodyParenthesized}"
-        case (binary @ (Implies | Iff | And | Or), Seq(l, r)) =>
-          val precedences: Map[ConnectorLabel, Int] = Map(
-            And -> 1,
-            Or -> 2,
-            Implies -> 3,
-            Iff -> 4
-          )
-          val precedence = precedences(binary)
-          val isLeftParentheses = l match {
-            case _: BinderFormula => true
-            case PredicateFormula(leftLabel, _) => nonAtomicPredicates.contains(leftLabel)
-            case ConnectorFormula(leftLabel, _) => precedences.get(leftLabel).exists(_ >= precedence)
-          }
-          val isRightParentheses = r match {
-            case _: BinderFormula => !isRightMost
-            case PredicateFormula(leftLabel, _) => nonAtomicPredicates.contains(leftLabel)
-            case ConnectorFormula(rightLabel, _) => precedences.get(rightLabel).exists(_ > precedence)
-          }
-          val (leftString, rightString) = (prettyFormulaInternal(l, isLeftParentheses, compact), prettyFormulaInternal(r, isRightMost || isRightParentheses, compact))
-          val leftParenthesized = if (isLeftParentheses) prettyParentheses(leftString) else leftString
-          val rightParenthesized = if (isRightParentheses) prettyParentheses(rightString) else rightString
-          prettyInfix(label.id, leftParenthesized, rightParenthesized, compact)
-        case (nary @ (And | Or), args) if args.nonEmpty =>
-          // Rewriting to match the above case; namely op(a) --> a, and op(a, ...rest) --> op(a, op(...rest))
-          // Empty args aren't allowed here
-          // Invariant: args.size > 2
-          if (args.sizeIs == 1) {
-            prettyFormulaInternal(args.head, isRightMost, compact)
-          } else {
-            prettyFormulaInternal(ConnectorFormula(nary, Seq(args.head, ConnectorFormula(nary, args.tail))), isRightMost, compact)
-          }
-        case _ => prettyFunction(label.id, args.map(a => prettyFormulaInternal(a, isRightMost, compact)), compact)
-      }
-    case BinderFormula(label, bound, inner) =>
-      def accumulateNested(f: Formula, acc: Seq[VariableLabel]): (Seq[VariableLabel], Formula) = f match {
-        case BinderFormula(`label`, nestBound, nestInner) => accumulateNested(nestInner, nestBound +: acc)
-        case _ => (acc, f)
-      }
-
-      val (bounds, innerNested) = accumulateNested(inner, Seq(bound))
-      Seq(s"${label.id}${bounds.reverse.map(_.id).mkString(commaSeparator(compact))}.", prettyFormulaInternal(innerNested, true, compact)).mkString(spaceSeparator(compact))
-  }
-
   /**
    * Returns a string representation of this formula. See also [[prettyTerm]].
    * Example output:
@@ -136,7 +26,7 @@ object Printer {
    * @param compact whether spaces should be omitted between tokens
    * @return the string representation of this formula
    */
-  def prettyFormula(formula: Formula, compact: Boolean = false): String = prettyFormulaInternal(formula, true, compact)
+  def prettyFormula(formula: Formula, compact: Boolean = false): String = Parser.printFormula(formula)
 
   /**
    * Returns a string representation of this term. See also [[prettyFormula]].
@@ -149,48 +39,7 @@ object Printer {
    * @param compact whether spaces should be omitted between tokens
    * @return the string representation of this term
    */
-  def prettyTerm(term: Term, compact: Boolean = false): String = term match {
-    case VariableTerm(label) => s"?${label.id}"
-    case FunctionTerm(label, args) =>
-      label match {
-        case `emptySet` =>
-          args match {
-            case Seq() => prettyFunction("∅", Seq.empty, compact, dropParentheses = true)
-            case _ => throw new Exception
-          }
-        case `unorderedPair` =>
-          args match {
-            case Seq(l, r) => s"{${Seq(l, r).map(prettyTerm(_, compact)).mkString(commaSeparator(compact))}}"
-            case _ => throw new Exception
-          }
-        case `orderedPair` =>
-          args match {
-            case Seq(l, r) => s"(${Seq(l, r).map(prettyTerm(_, compact)).mkString(commaSeparator(compact))})"
-            case _ => throw new Exception
-          }
-        case `singleton` =>
-          args match {
-            case Seq(s) => s"{${prettyTerm(s)}}"
-            case _ => throw new Exception
-          }
-        case `powerSet` =>
-          args match {
-            case Seq(s) => prettyFunction("P", Seq(prettyTerm(s)), compact)
-            case _ => throw new Exception
-          }
-        case `unionSet` =>
-          args match {
-            case Seq(s) => prettyFunction("U", Seq(prettyTerm(s)), compact)
-            case _ => throw new Exception
-          }
-        case _ =>
-          val labelString = label match {
-            case ConstantFunctionLabel(id, _) => id
-            case SchematicFunctionLabel(id, _) => s"?$id"
-          }
-          prettyFunction(labelString, args.map(prettyTerm(_, compact)), compact)
-      }
-  }
+  def prettyTerm(term: Term, compact: Boolean = false): String = Parser.printTerm(term)
 
   /**
    * Returns a string representation of this sequent.
@@ -203,23 +52,7 @@ object Printer {
    * @param compact whether spaces should be omitted between tokens
    * @return the string representation of this sequent
    */
-  def prettySequent(sequent: Sequent, compact: Boolean = false): String = {
-    def prettyFormulas(set: Set[Formula]): String = set.toSeq.map(prettyFormula(_, compact)).sorted.mkString(commaSeparator(compact, ";"))
-
-    Seq(prettyFormulas(sequent.left), "⊢", prettyFormulas(sequent.right)).filter(_.nonEmpty).mkString(spaceSeparator(compact))
-  }
-
-  /**
-   * Returns a string representation of the line number in a proof.
-   * Example output:
-   * <pre>
-   * 0:2:1
-   * </pre>
-   *
-   * @param line the line number
-   * @return the string representation of this line number
-   */
-  def prettyLineNumber(line: Seq[Int]): String = line.mkString(":")
+  def prettySequent(sequent: Sequent, compact: Boolean = false): String = Parser.printSequent(sequent)
 
   /**
    * Returns a string representation of this proof.
@@ -347,5 +180,4 @@ object Printer {
   }
 
   def prettySCProof(proof: SCProof): String = prettySCProof(SCValidProof(proof), false)
-
 }
-- 
GitLab