/benchmarks/scala-sat/cafesat/src/main/scala/cafesat/asts/core/Manip.scala

https://github.com/renaissance-benchmarks/renaissance · Scala · 318 lines · 286 code · 28 blank · 4 comment · 39 complexity · e6b7ce204bd8dab3a3c7ea1f4ca1ddba MD5 · raw file

  1. package cafesat.asts.core
  2. import Trees._
  3. import scala.collection.mutable.ListBuffer
  4. // when we apply some function to a quantified term, it does not affect the bound variables
  5. // If a map modify the quantified variable, we should maybe propagate in the bound term?
  6. // TODO: alpha renaming
  7. object Manip {
  8. def mapPreorder(t: Term, ff: (Formula) => Formula, ft: (Term) => Term): Term = mapPreorder(t, ff, ft, Nil)
  9. private def mapPreorder(t: Term, ff: (Formula) => Formula, ft: (Term) => Term, bv: List[Variable]): Term = t match {
  10. case v@Variable(_,_) if (bv.contains(v)) => v
  11. case _ => ft(t) match {
  12. case v@Variable(_, _) => v
  13. case FunctionApplication(s, ts) => {
  14. val res = FunctionApplication(s, ts.map(t => mapPreorder(t, ff, ft, bv)))
  15. res
  16. }
  17. case ITE(c, t, e) => {
  18. val newC = mapPreorder(c, ff, ft, bv)
  19. val newT = mapPreorder(t, ff, ft, bv)
  20. val newE = mapPreorder(e, ff, ft, bv)
  21. ITE(newC, newT, newE)
  22. }
  23. case TermQuantifierApplication(s, v, ts) => TermQuantifierApplication(s, v, ts.map(t => mapPreorder(t, ff, ft, v :: bv)))
  24. }
  25. }
  26. def mapPostorder(t: Term, ff: (Formula) => Formula, ft: (Term) => Term): Term = mapPostorder(t, ff, ft, Nil)
  27. private def mapPostorder(t: Term, ff: (Formula) => Formula, ft: (Term) => Term, bv: List[Variable]): Term = t match {
  28. case v@Variable(_, _) if bv.contains(v) => v
  29. case v@Variable(_, _) => ft(v)
  30. case FunctionApplication(s, ts) => {
  31. var newArgs: ListBuffer[Term] = new ListBuffer
  32. var oldArgs: List[Term] = ts
  33. while(!oldArgs.isEmpty) {
  34. newArgs.append(mapPostorder(oldArgs.head, ff, ft, bv))
  35. oldArgs = oldArgs.tail
  36. }
  37. ft(FunctionApplication(s, newArgs.toList))
  38. }
  39. case ITE(c, t, e) => {
  40. val newC = mapPostorder(c, ff, ft, bv)
  41. val newT = mapPostorder(t, ff, ft, bv)
  42. val newE = mapPostorder(e, ff, ft, bv)
  43. ft(ITE(newC, newT, newE))
  44. }
  45. case TermQuantifierApplication(s, v, ts) => ft(TermQuantifierApplication(s, v, ts.map(t => mapPostorder(t, ff, ft, v :: bv))))
  46. }
  47. def mapPreorder(f: Formula, ff: (Formula) => Formula, ft: (Term) => Term): Formula = mapPreorder(f, ff, ft, Nil)
  48. private def mapPreorder(f: Formula, ff: (Formula) => Formula, ft: (Term) => Term, bv: List[Variable]): Formula = ff(f) match {
  49. case PredicateApplication(s, ts) => PredicateApplication(s, ts.map(t => mapPreorder(t, ff, ft, bv)))
  50. case ConnectiveApplication(s, fs) => ConnectiveApplication(s, fs.map(f => mapPreorder(f, ff, ft, bv)))
  51. case QuantifierApplication(s, v, f) => QuantifierApplication(s, v, mapPreorder(f, ff, ft, v :: bv))
  52. }
  53. def mapPostorder(f: Formula, ff: (Formula) => Formula, ft: (Term) => Term): Formula = mapPostorder(f, ff, ft, Nil)
  54. private def mapPostorder(f: Formula, ff: (Formula) => Formula, ft: (Term) => Term, bv: List[Variable]): Formula = f match {
  55. case PredicateApplication(s, ts) => {
  56. var newArgs: ListBuffer[Term] = new ListBuffer
  57. var oldArgs: List[Term] = ts
  58. while(!oldArgs.isEmpty) {
  59. newArgs.append(mapPostorder(oldArgs.head, ff, ft, bv))
  60. oldArgs = oldArgs.tail
  61. }
  62. ff(PredicateApplication(s, newArgs.toList))
  63. }
  64. case ConnectiveApplication(s, fs) => {
  65. var newArgs: ListBuffer[Formula] = new ListBuffer
  66. var oldArgs = fs
  67. while(!oldArgs.isEmpty) {
  68. newArgs.append(mapPostorder(oldArgs.head, ff, ft, bv))
  69. oldArgs = oldArgs.tail
  70. }
  71. ff(ConnectiveApplication(s, newArgs.toList))
  72. }
  73. case QuantifierApplication(s, v, f) => ff(QuantifierApplication(s, v, mapPostorder(f, ff, ft, v :: bv)))
  74. }
  75. def foldPreorder[A](t: Term, z: A)(ff: (A, Formula) => A, ft: (A, Term) => A): A = foldPreorder(t, z, Nil)(ff, ft)
  76. def foldPreorder[A](t: Term, z: A, bv: List[Variable])(ff: (A, Formula) => A, ft: (A, Term) => A): A = t match {
  77. case v@Variable(_, _) if bv.contains(v) => z
  78. case v@Variable(_, _) => ft(z, v)
  79. case fa@FunctionApplication(_, ts) => {
  80. val tmp = ft(z, fa)
  81. ts.foldLeft(tmp)((a, t) => foldPreorder(t, a, bv)(ff, ft))
  82. }
  83. case ite@ITE(c, t, e) => {
  84. val tmp1 = ft(z, ite)
  85. val tmp2 = foldPreorder(c, tmp1, bv)(ff, ft)
  86. val tmp3 = foldPreorder(t, tmp2, bv)(ff, ft)
  87. foldPreorder(e, tmp3, bv)(ff, ft)
  88. }
  89. case tq@TermQuantifierApplication(s, v, ts) => {
  90. val tmp = ft(z, tq)
  91. ts.foldLeft(tmp)((a, t) => foldPreorder(t, a, v :: bv)(ff, ft))
  92. }
  93. }
  94. def foldPostorder[A](t: Term, z: A)(ff: (A, Formula) => A, ft: (A, Term) => A): A = foldPostorder(t, z, Nil)(ff, ft)
  95. def foldPostorder[A](t: Term, z: A, bv: List[Variable])(ff: (A, Formula) => A, ft: (A, Term) => A): A = t match {
  96. case v@Variable(_, _) if bv.contains(v) => z
  97. case v@Variable(_, _) => ft(z, v)
  98. case fa@FunctionApplication(_, ts) => {
  99. val tmp = ts.foldLeft(z)((a, t) => foldPostorder(t, a, bv)(ff, ft))
  100. ft(tmp, fa)
  101. }
  102. case ite@ITE(c, t, e) => {
  103. val tmp1 = foldPostorder(c, z, bv)(ff, ft)
  104. val tmp2 = foldPostorder(t, tmp1, bv)(ff, ft)
  105. val tmp3 = foldPostorder(e, tmp2, bv)(ff, ft)
  106. ft(tmp3, ite)
  107. }
  108. case tq@TermQuantifierApplication(s, v, ts) => {
  109. val tmp = ts.foldLeft(z)((a, t) => foldPostorder(t, a, v :: bv)(ff, ft))
  110. ft(tmp, tq)
  111. }
  112. }
  113. def foldPreorder[A](f: Formula, z: A)(ff: (A, Formula) => A, ft: (A, Term) => A): A = foldPreorder(f, z, Nil)(ff, ft)
  114. def foldPreorder[A](f: Formula, z: A, bv: List[Variable])(ff: (A, Formula) => A, ft: (A, Term) => A): A = f match {
  115. case p@PredicateApplication(_, ts) => {
  116. val tmp = ff(z, p)
  117. ts.foldLeft(tmp)((a, t) => foldPreorder(t, a, bv)(ff, ft))
  118. }
  119. case c@ConnectiveApplication(_, fs) => {
  120. val tmp = ff(z, c)
  121. fs.foldLeft(tmp)((a, f) => foldPreorder(f, a, bv)(ff, ft))
  122. }
  123. case q@QuantifierApplication(_, v, f) => {
  124. val tmp = ff(z, q)
  125. foldPreorder(f, tmp, v :: bv)(ff, ft)
  126. }
  127. }
  128. def foldPostorder[A](f: Formula, z: A)(ff: (A, Formula) => A, ft: (A, Term) => A): A = foldPostorder(f, z, Nil)(ff, ft)
  129. def foldPostorder[A](f: Formula, z: A, bv: List[Variable])(ff: (A, Formula) => A, ft: (A, Term) => A): A = f match {
  130. case p@PredicateApplication(_, ts) => {
  131. val tmp = ts.foldLeft(z)((a, t) => foldPreorder(t, a, bv)(ff, ft))
  132. ff(tmp, p)
  133. }
  134. case c@ConnectiveApplication(_, fs) => {
  135. val tmp = fs.foldLeft(z)((a, f) => foldPreorder(f, a, bv)(ff, ft))
  136. ff(tmp, c)
  137. }
  138. case q@QuantifierApplication(_, v, f) => {
  139. val tmp = foldPreorder(f, z, v :: bv)(ff, ft)
  140. ff(tmp, q)
  141. }
  142. }
  143. def foreachPreorder(t: Term, ff: (Formula) => Unit, ft: (Term) => Unit): Unit = foldPreorder(t, ())((_,f) => ff(f), (_,t) => ft(t))
  144. def foreachPreorder(f: Formula, ff: (Formula) => Unit, ft: (Term) => Unit): Unit = foldPreorder(f, ())((_, f) => ff(f), (_, t) => ft(t))
  145. def foreachPostorder(t: Term, ff: (Formula) => Unit, ft: (Term) => Unit): Unit = foldPostorder(t, ())((_, f) => ff(f), (_, t) => ft(t))
  146. def foreachPostorder(f: Formula, ff: (Formula) => Unit, ft: (Term) => Unit): Unit = foldPostorder(f, ())((_, f) => ff(f), (_, t) => ft(t))
  147. def exists(t: Term, pf: (Formula) => Boolean, pt: (Term) => Boolean): Boolean = foldPostorder(t, false)((b, f) => b || pf(f), (b, t) => (b || pt(t)))
  148. def exists(f: Formula, pf: (Formula) => Boolean, pt: (Term) => Boolean): Boolean = foldPostorder(f, false)((b, f) => b || pf(f), (b, t) => (b || pt(t)))
  149. def exists(t: Term, pt: (Term) => Boolean): Boolean = exists(t, (_: Formula) => false, pt)
  150. def exists(f: Formula, pf: (Formula) => Boolean): Boolean = exists(f, pf, (_: Term) => false)
  151. def forall(t: Term, pf: (Formula) => Boolean, pt: (Term) => Boolean): Boolean = foldPostorder(t, true)((b, f) => b && pf(f), (b, t) => (b && pt(t)))
  152. def forall(f: Formula, pf: (Formula) => Boolean, pt: (Term) => Boolean): Boolean = foldPostorder(f, true)((b, f) => b && pf(f), (b, t) => (b && pt(t)))
  153. def forall(t: Term, pt: (Term) => Boolean): Boolean = forall(t, (_: Formula) => true, pt)
  154. def forall(f: Formula, pf: (Formula) => Boolean): Boolean = forall(f, pf, (_: Term) => true)
  155. def count(t: Term, pf: (Formula) => Boolean, pt: (Term) => Boolean): Int = foldPostorder(t, 0)(
  156. (a, f) => if(pf(f)) a + 1 else a,
  157. (a, t) => if(pt(t)) a + 1 else a)
  158. def count(f: Formula, pf: (Formula) => Boolean, pt: (Term) => Boolean): Int = foldPostorder(f, 0)(
  159. (a, f) => if(pf(f)) a + 1 else a,
  160. (a, t) => if(pt(t)) a + 1 else a)
  161. def count(t: Term, pt: (Term) => Boolean): Int = count(t, (_: Formula) => false, pt)
  162. def count(f: Formula, pf: (Formula) => Boolean): Int = count(f, pf, (_: Term) => false)
  163. def size(t: Term): Int = count(t, (f: Formula) => true, (t: Term) => true)
  164. def size(f: Formula): Int = count(f, (f: Formula) => true, (t: Term) => true)
  165. def vars(t: Term): Set[Variable] = foldPostorder(t, Set[Variable]())((a, f) => a, (a, t) => t match {
  166. case v@Variable(_, _) => a + v
  167. case _ => a
  168. })
  169. def vars(f: Formula): Set[Variable] = foldPostorder(f, Set[Variable]())((a, f) => a, (a, t) => t match {
  170. case v@Variable(_, _) => a + v
  171. case _ => a
  172. })
  173. def substitute(t: Term, m: Map[Variable, Term]): Term = mapPostorder(t, f => f, t => t match {
  174. case v@Variable(_,_) => m.get(v) match {
  175. case Some(a) => a
  176. case None => v
  177. }
  178. case t@_ => t
  179. })
  180. def substitute(t: Term, oldVar: Variable, newT: Term): Term = substitute(t, Map(oldVar -> newT))
  181. def substitute(f: Formula, m: Map[Variable, Term]): Formula = mapPostorder(f, f => f, t => t match {
  182. case v@Variable(_, _) => m.get(v) match {
  183. case Some(a) => a
  184. case None => v
  185. }
  186. case t@_ => t
  187. })
  188. def substitute(f: Formula, oldVar: Variable, newT: Term): Formula = substitute(f, Map(oldVar -> newT))
  189. def contains(t: Term, elem: Term): Boolean = foldPostorder(t, false)((b, f) => false,(b, t2) => b || elem == t2)
  190. def contains(f: Formula, elem: Term): Boolean = foldPostorder(f, false)((b, f) => false, (b, t2) => b || elem == t2)
  191. //find a node that verify a predicate and apply a function on it and return. Only find one such element even if several are present
  192. private def findAndMap(f: Formula, pf: (Formula) => Boolean, pt: (Term) => Boolean, ff: (Formula) => Formula, ft: (Term) => Term, bv: List[Variable]): (Formula, Boolean) = if(pf(f)) (ff(f), true) else (f match {
  193. case PredicateApplication(s, ts) => {
  194. var found = false
  195. val rts = ts.map(t => {
  196. if(found)
  197. t
  198. else {
  199. val (nt, b) = findAndMap(t, pf, pt, ff, ft, bv)
  200. found = b
  201. nt
  202. }
  203. })
  204. (PredicateApplication(s, rts), found)
  205. }
  206. case ConnectiveApplication(s, fs) => {
  207. var found = false
  208. val rts = fs.map(f => {
  209. if(found)
  210. f
  211. else {
  212. val (nf, b) = findAndMap(f, pf, pt, ff, ft, bv)
  213. found = b
  214. nf
  215. }
  216. })
  217. (ConnectiveApplication(s, rts), found)
  218. }
  219. case QuantifierApplication(s, v, f) => {
  220. val (nf, found) = findAndMap(f, pf, pt, ff, ft, v :: bv)
  221. (QuantifierApplication(s, v, nf), found)
  222. }
  223. })
  224. private def findAndMap(t: Term, pf: (Formula) => Boolean, pt: (Term) => Boolean, ff: (Formula) => Formula, ft: (Term) => Term, bv: List[Variable]): (Term, Boolean) = t match {
  225. case v@Variable(_,_) if (bv.contains(v)) => (v, false)
  226. case _ => if(pt(t)) (ft(t), true) else (t match {
  227. case v@Variable(_, _) => (v, false)
  228. case FunctionApplication(s, ts) => {
  229. var found = false
  230. val rts = ts.map(t => {
  231. if(found)
  232. t
  233. else {
  234. val (nt, b) = findAndMap(t, pf, pt, ff, ft, bv)
  235. found = b
  236. nt
  237. }
  238. })
  239. (FunctionApplication(s, rts), found)
  240. }
  241. case ITE(c, t, e) => {
  242. val (newC, b1) = findAndMap(c, pf, pt, ff, ft, bv)
  243. if(b1)
  244. (ITE(newC, t, e), true)
  245. else {
  246. val (newT, b2) = findAndMap(t, pf, pt, ff, ft, bv)
  247. if(b2)
  248. (ITE(newC, newT, e), true)
  249. else {
  250. val (newE, b3) = findAndMap(e, pf, pt, ff, ft, bv)
  251. (ITE(newC, newT, newE), b3)
  252. }
  253. }
  254. }
  255. case TermQuantifierApplication(s, v, ts) => sys.error("not supported")
  256. })
  257. }
  258. def findAndMap(f: Formula, pf: (Formula) => Boolean, pt: (Term) => Boolean, ff: (Formula) => Formula, ft: (Term) => Term): (Formula, Boolean) =
  259. findAndMap(f, pf, pt, ff, ft, List())
  260. def findAndMap(t: Term, pf: (Formula) => Boolean, pt: (Term) => Boolean, ff: (Formula) => Formula, ft: (Term) => Term): (Term, Boolean) =
  261. findAndMap(t, pf, pt, ff, ft, List())
  262. def alphaRenaming(formula: Formula): Formula = {
  263. var globalVars: Map[Variable, Variable] = Map()
  264. def recForm(f: Formula, bv: Map[Variable, Variable]): Formula = f match {
  265. case QuantifierApplication(s, v, b) => {
  266. val newName = freshVariable(v)
  267. QuantifierApplication(s, newName, recForm(b, bv + (v -> newName)))
  268. }
  269. case PredicateApplication(s, ts) => PredicateApplication(s, ts.map(t => recTerm(t, bv)))
  270. case ConnectiveApplication(s, fs) => ConnectiveApplication(s, fs.map(f => recForm(f, bv)))
  271. }
  272. def recTerm(t: Term, bv: Map[Variable, Variable]): Term = t match {
  273. case v@Variable(_,_) => bv.get(v) match {
  274. case Some(nv) => nv
  275. case None => globalVars.get(v) match {
  276. case Some(nv) => nv
  277. case None => {
  278. val nv = freshVariable(v)
  279. globalVars += (v -> nv)
  280. nv
  281. }
  282. }
  283. }
  284. case FunctionApplication(s, ts) => FunctionApplication(s, ts.map(t => recTerm(t, bv)))
  285. case ITE(c, t, e) => ITE(recForm(c, bv), recTerm(t, bv), recTerm(e, bv))
  286. case TermQuantifierApplication(s, v, ts) => sys.error("TODO")
  287. }
  288. recForm(formula, Map())
  289. }
  290. }