@@ -157,15 +157,16 @@ object Tableau extends ProofTactic with ProofSequentTactic with ProofFactSequent
157157
158158 import Branch .*
159159 override def toString (): String =
160- val pretUnif = unifiable.map((x, f) => x.id + " -> " + f._1.repr + " : " + f._2).mkString(" Unif(" , " , " , " )" )
160+ val pretUnif = unifiable.map((x, f) => x.repr + " -> " + f._1.repr + " : " + f._2).mkString(" Unif(" , " , " , " )" )
161161 // val pretTried = triedInstantiation.map((x, t) => x.id + " -> " + prettyTerm(t, true)).mkString("Tried(", ", ", ")")
162162 (s " Branch( " +
163163 s " ${RED (prettyIte(alpha, " alpha" ))}, " +
164164 s " ${GREEN (prettyIte(beta, " beta" ))}, " +
165165 s " ${BLUE (prettyIte(delta, " delta" ))}, " +
166166 s " ${YELLOW (prettyIte(gamma, " gamma" ))}, " +
167- s " ${MAGENTA (prettyIte(atoms._1, " +" ))}, ${CYAN (prettyIte(atoms._2, " -" ))}, " +
168- s " $pretUnif, _, _) " ).split(" '" ).mkString(" " ).split(" _" ).mkString(" " )
167+ s " ${MAGENTA (prettyIte(atoms._1, " +" ))}, ${CYAN (prettyIte(atoms._2, " -" ))}, " + " "
168+ // s"$pretUnif, _, _)"
169+ ).split(" '" ).mkString(" " ).split(" _" ).mkString(" " )
169170
170171 }
171172 object Branch {
@@ -196,35 +197,35 @@ object Tableau extends ProofTactic with ProofSequentTactic with ProofFactSequent
196197 }
197198 type Substitution = Map [Variable , Expression ]
198199 val Substitution = HashMap
199- def prettySubst (s : Substitution ): String = s.map((x, t) => x.id + " -> " + t.repr).mkString(" Subst(" , " , " , " )" )
200+ def prettySubst (s : Substitution ): String = s.map((x, t) => x.repr + " -> " + t.repr).mkString(" Subst(" , " , " , " )" )
200201
201202 /**
202203 * Detect if two terms can be unified, and if so, return a substitution that unifies them.
203204 */
204- def unify (t1 : Expression , t2 : Expression , current : Substitution , br : Branch ): Option [Substitution ] = (t1, t2) match
205+ def unify (t1 : Expression , t2 : Expression , current : Substitution , br : Branch ): Set [Substitution ] = (t1, t2) match
205206 case (x : Variable , y : Variable ) if (br.unifiable.contains(x) || x.id.no > br.maxIndex) && (br.unifiable.contains(y) || y.id.no > br.maxIndex) =>
206- if x == y then Some (current)
207+ if x == y then Set (current)
207208 else if current.contains(x) then unify(current(x), t2, current, br)
208209 else if current.contains(y) then unify(t1, current(y), current, br)
209- else Some (current + (x -> y))
210+ else Set (current + (x -> y), current + (y -> x ))
210211 case (x : Variable , t2 : Expression ) if br.unifiable.contains(x) || x.id.no > br.maxIndex =>
211212 val newt2 = substituteVariables(t2, current)
212- if newt2.freeVariables.contains(x) then None
213+ if newt2.freeVariables.contains(x) then Set .empty
213214 else if (current.contains(x)) unify(current(x), newt2, current, br)
214- else Some (current + (x -> newt2))
215+ else Set (current + (x -> newt2))
215216 case (t1 : Expression , y : Variable ) if br.unifiable.contains(y) || y.id.no > br.maxIndex =>
216217 val newt1 = substituteVariables(t1, current)
217- if newt1.freeVariables.contains(y) then None
218+ if newt1.freeVariables.contains(y) then Set .empty
218219 else if (current.contains(y)) unify(newt1, current(y), current, br)
219- else Some (current + (y -> newt1))
220+ else Set (current + (y -> newt1))
220221 case (Application (f1, a1), Application (f2, a2)) =>
221222 unify(f1, f2, current, br).flatMap(s => unify(a1, a2, s, br))
222- case _ => if t1 == t2 then Some (current) else None
223+ case _ => if t1 == t2 then Set (current) else Set .empty
223224
224225 /**
225226 * Detect if two atoms can be unified, and if so, return a substitution that unifies them.
226227 */
227- def unifyPred (pos : Expression , neg : Expression , br : Branch ): Option [Substitution ] = {
228+ def unifyPred (pos : Expression , neg : Expression , br : Branch ): Set [Substitution ] = {
228229 assert(pos.sort == Prop && neg.sort == Prop )
229230 unify(pos, neg, Substitution .empty, br)
230231
@@ -251,13 +252,9 @@ object Tableau extends ProofTactic with ProofSequentTactic with ProofFactSequent
251252 val neg = branch.atoms._2.iterator
252253 while (neg.hasNext) {
253254 val n = neg.next()
254- unifyPred(p, n, branch) match
255- case None => ()
256- case Some (unif) =>
257- substitutions = (unif, Set (p, ! n)) :: substitutions
255+ substitutions = unifyPred(p, n, branch).map(s => (s, Set (p, ! n))).toList ++ substitutions
258256 }
259257 }
260-
261258 val cr1 = substitutions.map((sub, set) =>
262259 (
263260 sub.flatMap((v, t) =>
@@ -277,7 +274,6 @@ object Tableau extends ProofTactic with ProofSequentTactic with ProofFactSequent
277274 v
278275 )
279276 )
280-
281277 bestSubst(cr, branch)
282278
283279 }
@@ -287,6 +283,7 @@ object Tableau extends ProofTactic with ProofSequentTactic with ProofFactSequent
287283 val minSize = substs.minBy(_._1.size)
288284 val smallSubst = substs.filter(_._1.size == minSize._1.size)
289285 // Up to this, it is necessary for completeness. From this, it is heuristic.
286+ // println("subst_with_score: " + smallSubst.map(s => prettySubst(s._1) + " using " + s._2.map(_.repr).mkString("{", ", ", "}") + " score: " + substitutionScore(s._1, branch)).mkString(" | "))
290287
291288 val best = smallSubst.minBy(s => substitutionScore(s._1, branch))
292289 Some (best)
@@ -340,16 +337,15 @@ object Tableau extends ProofTactic with ProofSequentTactic with ProofFactSequent
340337 * Explodes one Exists formula
341338 * Add the unquantified formula to the branch
342339 * Since the bound variable is not marked as suitable for instantiation, it behaves as a constant symbol (skolem)
340+ * Always uses a fresh variable to avoid clashes with gamma metavariables that may share the same name.
343341 */
344342 def delta (branch : Branch ): (Branch , Variable , Expression ) = {
345343 val f = branch.delta.head
346344 f match
347345 case Exists (v, body) =>
348- if branch.skolemized.contains(v) then
349- val newV = Variable (Identifier (v.id.name, branch.maxIndex), Ind )
350- val newInner = substituteVariables(body, Map (v -> newV))
351- (branch.copy(delta = branch.delta.tail, maxIndex = branch.maxIndex + 1 ).prepended(newInner), newV, newInner)
352- else (branch.copy(delta = branch.delta.tail, skolemized = branch.skolemized + v).prepended(body), v, body)
346+ val newV = Variable (Identifier (v.id.name, branch.maxIndex), Ind )
347+ val newInner = substituteVariables(body, Map (v -> newV))
348+ (branch.copy(delta = branch.delta.tail, skolemized = branch.skolemized + v, maxIndex = branch.maxIndex + 1 ).prepended(newInner), newV, newInner)
353349 case _ => throw Exception (" Error: First formula of delta is not an Exists" )
354350 }
355351
@@ -479,6 +475,8 @@ object Tableau extends ProofTactic with ProofSequentTactic with ProofFactSequent
479475 )
480476 else if (closeSubst.nonEmpty && closeSubst.get._1.nonEmpty) // If branch can be closed with Instantiation (LeftForall)
481477 val (x, t) = closeSubst.get._1.minBy((x, t) => branch.varsOrder(x))
478+ // println("Instantiating " + x.id + " with " + t.repr)
479+ // println("Branch before instantiation: " + branch)
482480 val (recBranch, instantiated) = applyInst(branch, x, t)
483481 val upperProof = decide(recBranch)
484482 upperProof.map((proof, step) =>
@@ -504,4 +502,4 @@ object Tableau extends ProofTactic with ProofSequentTactic with ProofFactSequent
504502 case c : Constant => c
505503 case Application (f, a) => Application (instantiate(f, x, t), instantiate(a, x, t))
506504 case Lambda (v, inner) => if (v == x) f else Lambda (v, instantiate(inner, x, t))
507- }
505+ }
0 commit comments