Skip to content

Commit

Permalink
changes to make sbt build work
Browse files Browse the repository at this point in the history
  • Loading branch information
msaxena2 committed May 20, 2017
1 parent 9509a5e commit 9e315fd
Show file tree
Hide file tree
Showing 6 changed files with 740 additions and 575 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ libraryDependencies ++= Seq(
"io.circe" %% "circe-generic" % "0.7.0",
"io.circe" %% "circe-parser" % "0.7.0",

"org.kframework.k" %% "kore" % "1.0-SNAPSHOT"
"org.kframework.k" %% "kore" % "0.5-SNAPSHOT"
)

lazy val installZ3 = taskKey[Unit]("Install Z3 theorem prover")
Expand Down
158 changes: 158 additions & 0 deletions src/main/scala/org/kframework/backend/skala/POSet.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// Copyright (c) 2015 K Team. All Rights Reserved.
package org.kframework.backend.skala

import java.util
import java.util.Optional

import scala.collection.JavaConverters._
import scala.collection._

case class CircularityException[T](cycle: Seq[T]) extends Exception(cycle.mkString(" < "))

/**
* A partially ordered set based on an initial set of direct relations.
*/
class POSet[T](directRelations: Set[(T, T)]) extends Serializable {

// convert the input set of relations to Map form for performance
private val directRelationsMap: Map[T, Set[T]] = directRelations groupBy { _._1 } mapValues { _ map { _._2 } toSet } map identity

/**
* Internal private method. Computes the transitive closer of the initial relations.
* It also checks for cycles during construction and throws an exception if it finds any.
*
* The implementation is simple. It links each element to the successors of its successors.
* TODO: there may be a more efficient algorithm (low priority)
*/
private def transitiveClosure(relations: Map[T, Set[T]]): Map[T, Set[T]] = {
val newRelations = relations map {
case (start, succ) =>
val newSucc = succ flatMap { relations.getOrElse(_, Set()) }
if (newSucc.contains(start))
constructAndThrowCycleException(start, start, Seq())
(start, succ | newSucc)
}
if (relations != newRelations) transitiveClosure(newRelations) else relations
}

/**
* Recursive method constructing and throwing and the cycle exception.
*
* @param start (or tail) element to look for when constructing the cycle
* @param current element
* @param path so far
*/
private def constructAndThrowCycleException(start: T, current: T, path: Seq[T]) {
val currentPath = path :+ current
val succs = directRelationsMap.getOrElse(current, Set())
if (succs.contains(start))
throw new CircularityException(currentPath :+ start)

succs foreach { constructAndThrowCycleException(start, _, currentPath) }
}

/**
* All the relations of the POSet, including the transitive ones.
*/
val relations = transitiveClosure(directRelationsMap)

def <(x: T, y: T): Boolean = relations.get(x).exists(_.contains(y))
def <=(x: T, y: T): Boolean = <(x, y) || x == y
def >(x: T, y: T): Boolean = relations.get(y).exists(_.contains(x))
def >=(x: T, y: T): Boolean = >(x, y) || x == y
def ~(x: T, y: T) = <(x, y) || <(y, x)

/**
* Returns true if x < y
*/
def lessThan(x: T, y: T): Boolean = <(x, y)
def lessThanEq(x: T, y: T): Boolean = <=(x, y)
def directlyLessThan(x: T, y: T): Boolean = directRelationsMap.get(x).exists(_.contains(y))
/**
* Returns true if y < x
*/
def greaterThan(x: T, y: T): Boolean = >(x, y)
def greaterThanEq(x: T, y: T): Boolean = >=(x, y)
def directlyGreaterThan(x: T, y: T): Boolean = directRelationsMap.get(y).exists(_.contains(x))
/**
* Returns true if y < x or y < x
*/
def inSomeRelation(x: T, y: T) = this.~(x, y)
def inSomeRelationEq(x: T, y: T) = this.~(x, y) || x == y

/**
* Returns an Optional of the least upper bound if it exists, or an empty Optional otherwise.
*/
lazy val leastUpperBound: Optional[T] = lub match {
case Some(x) => Optional.of(x)
case None => Optional.empty()
}

lazy val lub: Option[T] = {
val candidates = relations.values reduce { (a, b) => a & b }

if (candidates.size == 0)
None
else if (candidates.size == 1)
Some(candidates.head)
else {
val allPairs = for (a <- candidates; b <- candidates) yield { (a, b) }
if (allPairs exists { case (a, b) => ! ~(a, b) })
None
else
Some(
candidates.min(new Ordering[T]() {
def compare(x: T, y: T) = if (x < y) -1 else if (x > y) 1 else 0
}))
}
}

lazy val asOrdering: Ordering[T] = (x: T, y: T) => if (lessThanEq(x, y)) -1 else if (lessThanEq(y, x)) 1 else 0

/**
* Return the subset of items from the argument which are not
* less than any other item.
*/
def maximal(sorts: Iterable[T]): Set[T] =
sorts.filter(s1 => !sorts.exists(s2 => lessThan(s1, s2))).toSet

def maximal(sorts: util.Collection[T]): util.Set[T] = {
maximal(sorts.asScala).asJava
}

/**
* Return the subset of items from the argument which are not
* greater than any other item.
*/
def minimal(sorts: Iterable[T]): Set[T] =
sorts.filter(s1 => !sorts.exists(s2 => >(s1, s2))).toSet

def minimal(sorts: util.Collection[T]): util.Set[T] = {
maximal(sorts.asScala).asJava
}

override def toString() = {
"POSet(" + (relations flatMap { case (from, tos) => tos map { case to => from + "<" + to } }).mkString(",") + ")"
}

override def hashCode = relations.hashCode()

override def equals(that: Any) = that match {
case that: POSet[_] => relations == that.relations
case _ => false
}
}

object POSet {
def apply[T](relations: (T, T)*) = new POSet(relations.toSet)
def apply[T](s: Set[(T, T)]) = new POSet(s)

/**
* Import this for Scala syntactic sugar.
*/
implicit class PO[T](x: T)(implicit val po: POSet[T]) {
def <(y: T) = po.<(x, y)
def >(y: T) = po.>(x, y)
}
}

127 changes: 70 additions & 57 deletions src/main/scala/org/kframework/backend/skala/SkalaBackend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,71 @@ package org.kframework.backend.skala
import org.kframework.backend.skala.backendImplicits._
import org.kframework.kale.builtin.MapLabel
import org.kframework.kale.standard._
import org.kframework.kale.util.Named
import org.kframework.kale.util.{Named, fixpoint}
import org.kframework.kale.{Rewrite => _, _}
import org.kframework.kore
import org.kframework.kore.extended.Backend
import org.kframework.kore.extended.implicits._
import org.kframework.kore.implementation.DefaultBuilders
import org.kframework.kore.{Pattern, extended}
import org.kframework.kore.{Pattern, Rule, extended}

import scala.collection.Seq


class SkalaBackend(implicit val env: StandardEnvironment, val originalDefintion: kore.Definition) extends KoreBuilders with extended.Backend {
class SkalaBackend(implicit val env: StandardEnvironment, implicit val originalDefintion: kore.Definition, val module: kore.Module) extends KoreBuilders with extended.Backend {

override def att: kore.Attributes = originalDefintion.att

override def modules: Seq[kore.Module] = originalDefintion.modules
override def modules: Seq[kore.Module] = module +: originalDefintion.modulesMap.get(module.name).get.imports

val functionLabels = env.uniqueLabels.filter(_._2.isInstanceOf[FunctionDefinedByRewriting])

val functionalRules: Set[kore.Rule] = modules.flatMap(_.rules).filter(functionalFilter).toSet
val functionalLabelRulesMap: Map[Label, Set[Rule]] = modules.flatMap(_.rules).collect({
case r@kore.Rule(kore.Implies(_, kore.And(kore.Rewrite(kore.Application(kore.Symbol(label), _), _), _)), att) if functionLabels.contains(label) => (env.label(label), r)
}).groupBy(_._1).mapValues(_.map(_._2).toSet)

val functionalRules: Set[kore.Rule] = functionalLabelRulesMap.values.flatten.toSet

val regularRules: Set[Rewrite] = (modules.flatMap(_.rules).toSet[kore.Rule] -- functionalRules).map(StandardConverter.apply)

processFunctionRules(functionalLabelRulesMap)

val substitutionApplier = SubstitutionWithContext(_)

val unifier: MatcherOrUnifier = SingleSortedMatcher()

val rewriterGenerator = Rewriter(substitutionApplier, unifier)
implicit val rewriterGenerator = Rewriter(substitutionApplier, unifier)

val rewriter = rewriterGenerator(regularRules)

private def functionalFilter(r: kore.Rule): Boolean = r match {
case kore.Rule(kore.Implies(_, kore.And(kore.Rewrite(kore.Application(kore.Symbol(label), _), _), _)), att) => functionLabels.contains(label)
override def step(p: Pattern, steps: Int): Pattern = rewriter(p.asInstanceOf[Term]).toList.head

private def processFunctionRules(functionalLabelRulesMap: Map[Label, Set[Rule]]): Unit = {
val functionalLabelRewriteMap: Map[Label, Set[Rewrite]] = functionalLabelRulesMap.mapValues(x => x.map(StandardConverter.apply))

val functionRulesWithRenamedVariables: Map[Label, Set[Rewrite]] = functionalLabelRewriteMap.map({ case (k, v) => (k, v map env.renameVariables) })

setFunctionRules(functionRulesWithRenamedVariables)

val finalFunctionRules = fixpoint(resolveFunctionRHS)(functionalLabelRewriteMap)
setFunctionRules(finalFunctionRules)
}

override def step(p: Pattern, steps: Int): Pattern = rewriter(p.asInstanceOf[Term]).toList.head
def setFunctionRules(functionRules: Map[Label, Set[Rewrite]]) {
env.labels.collect({
case l: FunctionDefinedByRewriting => l.setRules(functionRules.getOrElse(l, Set()))(x => rewriterGenerator(x))
})
}

private def reconstruct(inhibitForLabel: Label)(t: Term): Term = t match {
case Node(label, children) if label != inhibitForLabel => label(children map reconstruct(inhibitForLabel))
case t => t
}

private def resolveFunctionRHS(functionRules: Map[Label, Set[Rewrite]]): Map[Label, Set[Rewrite]] =
functionRules map { case (label, rewrites) => (label, rewrites map (rw => reconstruct(label)(rw).asInstanceOf[Rewrite])) }


}

//Todo: Move somewhere else
Expand Down Expand Up @@ -68,6 +97,23 @@ object Hook {
}
}

case class IsSort(s: kore.Sort, m: kore.Module, implicit val d: kore.Definition)(implicit env: Environment) extends Named(s.toString) with FunctionLabel1 {

import org.kframework.kore.implementation.{DefaultBuilders => db}

override def f(_1: Term): Option[Term] = {
if (!_1.isGround)
None
else {
val ss = m.sortsFor(db.Symbol(_1.label.name))
ss.map(x => m.subsorts.<=(x, s)).filter(_)
if (ss.nonEmpty) {
Some(env.Truth(true))
}
None
}
}
}

object DefinitionToStandardEnvironment extends (kore.Definition => StandardEnvironment) {

Expand Down Expand Up @@ -99,32 +145,19 @@ object DefinitionToStandardEnvironment extends (kore.Definition => StandardEnvir


def apply(d: kore.Definition, m: kore.Module): StandardEnvironment = {
import org.kframework.kore.implementation.{DefaultBuilders => db}

implicit val iDef = d

case class IsSort(s: kore.Sort)(implicit env: Environment) extends Named(s.toString) with FunctionLabel1 {
override def f(_1: Term): Option[Term] = {
if (!_1.isGround)
None
else {
val ss = m.sortsFor(db.Symbol(_1.label.name))
ss.map(x => m.subsorts.<=(x, s)).filter(_)
if (ss.nonEmpty) {
Some(env.Truth(true))
}
None
}
}
}

val allImports = m.imports


val uniqueSymbolDecs: Seq[kore.SymbolDeclaration] = m.allSentences.collect({
case sd@kore.SymbolDeclaration(_, s, _, _) if s != iNone => sd
case sd@kore.SymbolDeclaration(_, s, _, _) => sd
}).groupBy(_.symbol).mapValues(_.head).values.toSeq


val sortDeclarations: Seq[kore.SortDeclaration] = m.sentences.collect({
val sortDeclarations: Seq[kore.SortDeclaration] = m.allSentences.collect({
case s@kore.SortDeclaration(_, _) => s
})

Expand All @@ -136,11 +169,6 @@ object DefinitionToStandardEnvironment extends (kore.Definition => StandardEnvir
implicit val env = StandardEnvironment()


def declareSortPredicate(x: kore.SymbolDeclaration): Option[Label] = {
Some(IsSort(db.Sort(x.symbol.str)).asInstanceOf[Label])
}


def declareNonHookedSymbol(x: kore.SymbolDeclaration): Option[Label] = {
if (env.uniqueLabels.contains(x.symbol.str)) {
None
Expand All @@ -149,16 +177,16 @@ object DefinitionToStandardEnvironment extends (kore.Definition => StandardEnvir
x.att.findSymbol(Encodings.function) match {
case Some(_) => {
if (x.symbol.str.startsWith("is")) {
declareSortPredicate(x)
}

//Functional Symbol Declaration
x.args match {
case Seq() => Some(FunctionDefinedByRewritingLabel0(x.symbol.str)(env))
case Seq(_) => Some(FunctionDefinedByRewritingLabel1(x.symbol.str)(env))
case Seq(_, _) => Some(FunctionDefinedByRewritingLabel2(x.symbol.str)(env))
case Seq(_, _, _) => Some(FunctionDefinedByRewritingLabel3(x.symbol.str)(env))
case Seq(_, _, _, _) => Some(FunctionDefinedByRewritingLabel4(x.symbol.str)(env))
Some(IsSort(db.Sort(x.symbol.str), m, d))
} else {
//Functional Symbol Declaration
x.args match {
case Seq() => Some(FunctionDefinedByRewritingLabel0(x.symbol.str)(env))
case Seq(_) => Some(FunctionDefinedByRewritingLabel1(x.symbol.str)(env))
case Seq(_, _) => Some(FunctionDefinedByRewritingLabel2(x.symbol.str)(env))
case Seq(_, _, _) => Some(FunctionDefinedByRewritingLabel3(x.symbol.str)(env))
case Seq(_, _, _, _) => Some(FunctionDefinedByRewritingLabel4(x.symbol.str)(env))
}
}
}
//
Expand Down Expand Up @@ -220,20 +248,6 @@ object DefinitionToStandardEnvironment extends (kore.Definition => StandardEnvir
}
}).toSet


// Function Rules

val functionRulesAsLeftRight: Set[(Label, Rewrite)] = m.rules.collect({
case r@kore.Rule(kore.Implies(_, kore.And(kore.Rewrite(kore.Application(kore.Symbol(label), _), _), _)), att) if att.findSymbol(Encodings.function).isDefined =>
(env.label(label), StandardConverter(r))
}).toSet


val functionRules: Map[Label, Set[Rewrite]] = functionRulesAsLeftRight groupBy (_._1) map { case (k, set) => (k, set.map(_._2)) }

val functionRulesWithRenamedVariables: Map[Label, Set[Rewrite]] = functionRules map { case (k, v) => (k, v map env.renameVariables) }


env.seal()

env
Expand All @@ -256,9 +270,8 @@ object DefinitionToStandardEnvironment extends (kore.Definition => StandardEnvir
}

object SkalaBackend extends extended.BackendCreator {
override def apply(d: kore.Definition): Backend = new SkalaBackend()(DefinitionToStandardEnvironment(d), d)

// Todo: Use for Development, Replace with apply above
def apply(d: kore.Definition, m: kore.Module): Backend = new SkalaBackend()(DefinitionToStandardEnvironment(d, m), d)
def apply(d: kore.Definition, m: kore.Module): Backend = new SkalaBackend()(DefinitionToStandardEnvironment(d, m), d, m)
}

Loading

0 comments on commit 9e315fd

Please sign in to comment.