@@ -11,6 +11,7 @@ import scala.language.postfixOps
11
11
import scala .collection .mutable
12
12
import scala .reflect .internal .util .Statistics
13
13
import scala .reflect .internal .util .HashSet
14
+ import scala .annotation .tailrec
14
15
15
16
trait Logic extends Debugging {
16
17
import PatternMatchingStats ._
@@ -46,7 +47,7 @@ trait Logic extends Debugging {
46
47
type Tree
47
48
48
49
class Prop
49
- case class Eq (p : Var , q : Const ) extends Prop
50
+ final case class Eq (p : Var , q : Const ) extends Prop
50
51
51
52
type Const
52
53
@@ -103,39 +104,53 @@ trait Logic extends Debugging {
103
104
def implications : List [(Sym , List [Sym ], List [Sym ])]
104
105
}
105
106
107
+ private def propToLinkedHashSet (ops : Seq [Prop ]) = {
108
+ val set = new mutable.LinkedHashSet [Prop ]()
109
+ ops.foreach(set += _)
110
+ set
111
+ }
112
+
106
113
// would be nice to statically check whether a prop is equational or pure,
107
114
// but that requires typing relations like And(x: Tx, y: Ty) : (if(Tx == PureProp && Ty == PureProp) PureProp else Prop)
108
- case class And (a : Prop , b : Prop ) extends Prop
109
- case class Or (a : Prop , b : Prop ) extends Prop
110
- case class Not (a : Prop ) extends Prop
115
+ final case class And (ops : mutable.LinkedHashSet [Prop ]) extends Prop
116
+ object And {
117
+ def apply (ops : Prop * ) = new And (propToLinkedHashSet(ops))
118
+ }
119
+ final case class Or (ops : mutable.LinkedHashSet [Prop ]) extends Prop
120
+ object Or {
121
+ def apply (ops : Prop * ) = new Or (propToLinkedHashSet(ops))
122
+ }
123
+
124
+ final case class Not (a : Prop ) extends Prop
111
125
112
126
case object True extends Prop
113
127
case object False extends Prop
114
128
115
129
// symbols are propositions
116
- abstract case class Sym ( variable : Var , const : Const ) extends Prop {
130
+ final class Sym private [ PropositionalLogic ] ( val variable : Var , val const : Const ) extends Prop {
117
131
private val id : Int = Sym .nextSymId
118
132
119
- override def toString = variable + " =" + const + " #" + id
133
+ override def toString = variable + " =" + const + " #" + id
120
134
}
121
- class UniqueSym ( variable : Var , const : Const ) extends Sym (variable, const)
135
+
122
136
object Sym {
123
137
private val uniques : HashSet [Sym ] = new HashSet (" uniques" , 512 )
124
138
def apply (variable : Var , const : Const ): Sym = {
125
- val newSym = new UniqueSym (variable, const)
139
+ val newSym = new Sym (variable, const)
126
140
(uniques findEntryOrUpdate newSym)
127
141
}
128
- private def nextSymId = {_symId += 1 ; _symId}; private var _symId = 0
142
+ def nextSymId = {_symId += 1 ; _symId}; private var _symId = 0
129
143
implicit val SymOrdering : Ordering [Sym ] = Ordering .by(_.id)
130
144
}
131
145
132
- def / \ (props : Iterable [Prop ]) = if (props.isEmpty) True else props.reduceLeft(And (_, _))
133
- def \/ (props : Iterable [Prop ]) = if (props.isEmpty) False else props.reduceLeft(Or (_, _))
146
+ def / \ (props : Iterable [Prop ]) = if (props.isEmpty) True else And (props.toSeq: _* )
147
+ def \/ (props : Iterable [Prop ]) = if (props.isEmpty) False else Or (props.toSeq: _* )
148
+
134
149
135
150
trait PropTraverser {
136
151
def apply (x : Prop ): Unit = x match {
137
- case And (a, b ) => apply(a); apply(b)
138
- case Or (a, b ) => apply(a); apply(b)
152
+ case And (ops ) => ops foreach apply
153
+ case Or (ops ) => ops foreach apply
139
154
case Not (a) => apply(a)
140
155
case Eq (a, b) => applyVar(a); applyConst(b)
141
156
case _ =>
@@ -154,8 +169,8 @@ trait Logic extends Debugging {
154
169
155
170
trait PropMap {
156
171
def apply (x : Prop ): Prop = x match { // TODO: mapConserve
157
- case And (a, b ) => And (apply(a), apply(b) )
158
- case Or (a, b ) => Or (apply(a), apply(b) )
172
+ case And (ops ) => And (ops map apply)
173
+ case Or (ops ) => Or (ops map apply)
159
174
case Not (a) => Not (apply(a))
160
175
case p => p
161
176
}
@@ -255,8 +270,8 @@ trait Logic extends Debugging {
255
270
}
256
271
}
257
272
258
- debug.patmat(" eqAxioms:\n " + cnfString(toFormula( eqAxioms)) )
259
- debug.patmat(" pure:" + pure.map(p => cnfString(p)). mkString(" \n " ))
273
+ debug.patmat(s " eqAxioms: \n $ eqAxioms" )
274
+ debug.patmat(s " pure: ${ pure.mkString(" \n " )} " )
260
275
261
276
if (Statistics .canEnable) Statistics .stopTimer(patmatAnaVarEq, start)
262
277
0 commit comments