From 9cefe195dc89fac8cacf06d53ad2f554aa115cdc Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Tue, 28 Aug 2012 08:42:12 +0300 Subject: [PATCH 01/27] start to post naming and ordering. --- src/main/scala/termware/Name.scala | 57 ++++++++++++++++++++- src/main/scala/termware/PrimitiveTerm.scala | 6 +-- src/main/scala/termware/Substitution.scala | 53 +++++++++++++++++++ src/main/scala/termware/Term.scala | 3 +- src/main/scala/termware/TermOrdering.scala | 35 +++++++++++++ src/main/scala/termware/package.scala | 3 ++ 6 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 src/main/scala/termware/Substitution.scala create mode 100644 src/main/scala/termware/TermOrdering.scala diff --git a/src/main/scala/termware/Name.scala b/src/main/scala/termware/Name.scala index ca5b07c..d38b2f9 100644 --- a/src/main/scala/termware/Name.scala +++ b/src/main/scala/termware/Name.scala @@ -1,9 +1,62 @@ package termware -sealed trait Name +import scala.reflect.runtime.universe.TypeTag +import scala.reflect.runtime.universe.Type +import scala.reflect.runtime.universe.typeOf + + +sealed trait Name extends Ordered[Name] case class SymbolName(s:Symbol) extends Name -case class PrimitiveName[V](v:V) extends Name +{ + + def compare(x:Name):Int = + x match { + case SymbolName(sx) => if (s eq sx) 0 + else { + var c = s.hashCode - sx.hashCode + if (c!=0) { + c + } else { + s.toString.compare(sx.toString) + } + } + case PrimitiveName(v) => -1 + } + +} + +case class PrimitiveName[V:TypeTag](v:V)(implicit ord:Ordering[V]) extends Name +{ + + def valueType: Type = typeOf[V] + + def compare(x:Name):Int = + x match { + case SymbolName(_) => 1 + case xp@PrimitiveName(xv) => + var c = valueType.hashCode - xp.valueType.hashCode + if (c != 0) + c + else if (xp.valueType <:< valueType) + ord.compare(v, xv.asInstanceOf[V]) + else { + // hashCodes are equals but types are differeent + // very rare. + c = valueType.toString.compare(xp.valueType.toString) + if ( c == 0) { + // very-very-very rare. near newer + c = v.hashCode - xp.v.hashCode + if (c == 0) { + c = v.toString.compare(xp.v.toString) + } + } + c + } + + } + +} // vim: set ts=4 sw=4 et: diff --git a/src/main/scala/termware/PrimitiveTerm.scala b/src/main/scala/termware/PrimitiveTerm.scala index dcf7de1..0e2e687 100644 --- a/src/main/scala/termware/PrimitiveTerm.scala +++ b/src/main/scala/termware/PrimitiveTerm.scala @@ -4,7 +4,7 @@ import scala.reflect.runtime.universe._ import scala.math._ -abstract class PrimitiveToTerm[X:TypeTag] extends ToTerm[X] +abstract class PrimitiveToTerm[X:TypeTag](implicit ord:Ordering[X]) extends ToTerm[X] { def name(x:X):Name = PrimitiveName[X](x) @@ -34,7 +34,7 @@ abstract class PrimitiveToTerm[X:TypeTag] extends ToTerm[X] } -class NumericToTerm[X <% ScalaNumericConversions](implicit xtag:TypeTag[X]) extends PrimitiveToTerm[X] +class NumericToTerm[X <% ScalaNumericConversions](implicit xtag:TypeTag[X], ord:Ordering[X]) extends PrimitiveToTerm[X] { override def isNumber(x:X) = true @@ -57,7 +57,7 @@ object DoubleToTerm extends NumericToTerm[Double] // //object BigIntToTerm extends NumericToTerm[BigInt](typeTag[BigInt]) -class NonNumericPrimitiveToTerm[X:TypeTag] extends PrimitiveToTerm[X] +class NonNumericPrimitiveToTerm[X:TypeTag](implicit ord:Ordering[X]) extends PrimitiveToTerm[X] { def isNumber(x:X) = false diff --git a/src/main/scala/termware/Substitution.scala b/src/main/scala/termware/Substitution.scala new file mode 100644 index 0000000..b12ee89 --- /dev/null +++ b/src/main/scala/termware/Substitution.scala @@ -0,0 +1,53 @@ +package termware; + +import scala.collection.immutable.TreeMap + +trait Substitution extends PartialFunction[Term,Term] +{ + + def +(kv:(Term,Term)): (Boolean,Substitution) ; + + def withIndex(newZipIndex:BigInt): Substitution + + def lastZipIndex: BigInt; + +} + + +object STMSubstitution +{ + def empty = new STMSubstitution(TreeMap[Term,Pair[BigInt,Term]](),BigInt(1)); +} + + +class STMSubstitution(val v: Map[Term,Pair[BigInt,Term]], + val lastZipIndex: BigInt) + extends Substitution +{ + def withIndex(newZipIndex:BigInt):STMSubstitution = { + val cmp = lastZipIndex.compare(newZipIndex); + if (cmp > 0) + new STMSubstitution(v,newZipIndex) + else if (cmp < 0) + new STMSubstitution( + v.filter({ _._2._1 < newZipIndex }),newZipIndex) + else /* newZipIndex == lastZipIndex */ + this; + } + + def +(kv:(Term,Term)): (Boolean,Substitution) = { + val r = v.get(kv._1); + val zkv = kv._1->Pair(lastZipIndex,kv._2); + if (r==None) + (true,new STMSubstitution(v+zkv,lastZipIndex)) + else + ??? + //r.get._2.unify(kv._2,new STMSubstitution(v+zkv,lastZipIndex)).get + } + + override def isDefinedAt(t:Term) = v.isDefinedAt(t); + override def apply(t:Term):Term = v.apply(t)._2; + +} + + diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 4b5a771..c3120ff 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -3,7 +3,7 @@ package termware import scala.reflect.runtime.universe._ import scala.math._ -trait Term +trait Term { def name: Name @@ -31,6 +31,7 @@ trait Term //def subst(s:Substitution):ComputationBounds[Term] + } diff --git a/src/main/scala/termware/TermOrdering.scala b/src/main/scala/termware/TermOrdering.scala new file mode 100644 index 0000000..03b8d19 --- /dev/null +++ b/src/main/scala/termware/TermOrdering.scala @@ -0,0 +1,35 @@ +package termware + +object TermOrdering extends Ordering[Term] +{ + + //TODO: optimize, check one level before call trampoline. + def compare(x:Term, y:Term):Int = + cbCompare(x,y).get + + def cbCompare(x:Term, y:Term):ComputationBounds[Int] = + { + (x.arity - y.arity) match { + case c if c!=0 => Done(c) + case _ => + (x.name compare y.name) match { + case c if c!=0 => Done(c) + case _ => cbCompare(x.subterms, y.subterms) + } + } + } + + def cbCompare(x:IndexedSeq[Term], y:IndexedSeq[Term]):ComputationBounds[Int]= + { + if (x.isEmpty) + Done(if (y.isEmpty) 0 else -1) + else if (y.isEmpty) + Done(1) + else + cbCompare(x.head, y.head) flatMap { r => + if (r!=0) Done(r) else cbCompare(x.tail, y.tail) + } + } + +} + diff --git a/src/main/scala/termware/package.scala b/src/main/scala/termware/package.scala index 033fa64..5eb590e 100644 --- a/src/main/scala/termware/package.scala +++ b/src/main/scala/termware/package.scala @@ -18,4 +18,7 @@ package object termware { implicit val stringToTerm = new NonNumericPrimitiveToTerm[String] + + implicit val termOrdering: Ordering[Term] = TermOrdering + } From 2648acf02f2b7a4041255250c95bac0d157e003d Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Tue, 28 Aug 2012 08:50:16 +0300 Subject: [PATCH 02/27] adopted to 2.10-M7 --- build.sbt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 922d948..a8d0c14 100644 --- a/build.sbt +++ b/build.sbt @@ -3,16 +3,16 @@ name:="termware" organization:="com.github.termware" -scalaVersion := "2.10.0-M6" +scalaVersion := "2.10.0-M7" scalacOptions ++= Seq("-unchecked","-deprecation","-feature") version:="0.0.2" -libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.0-M6" +libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.0-M7" // hack to support scalatest -libraryDependencies += "org.scalatest" %% "scalatest" % "1.9-2.10.0-M6-B2" % "test" +libraryDependencies += "org.scalatest" %% "scalatest" % "1.9-2.10.0-M7-B1" % "test" From ad2d88e9c37867cbe5bd9a017a169ebb56b013be Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Tue, 2 Oct 2012 08:19:37 +0300 Subject: [PATCH 03/27] add scala-actors needed for test in dependencies --- build.sbt | 5 ++++- project/plugins.sbt | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index a8d0c14..1c6d3ec 100644 --- a/build.sbt +++ b/build.sbt @@ -11,8 +11,11 @@ version:="0.0.2" libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.0-M7" +libraryDependencies += "org.scala-lang" % "scala-actors" % "2.10.0-M7" + // hack to support scalatest -libraryDependencies += "org.scalatest" %% "scalatest" % "1.9-2.10.0-M7-B1" % "test" +//libraryDependencies += "org.scalatest" %% "scalatest" % "1.9-2.10.0-M7-B1" % "test" +libraryDependencies += "org.scalatest" % "scalatest_2.10.0-M7" % "2.0.M4-2.10.0-M7-B1" diff --git a/project/plugins.sbt b/project/plugins.sbt index b4e3b0c..f43936d 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += Classpaths.typesafeResolver -addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0") +//addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0") From f685b65b025aaa0d9ce18b9751f27ed2a898aeb2 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 23 Feb 2013 00:53:10 +0200 Subject: [PATCH 04/27] start to thnk about term sigrature. --- build.sbt | 8 +- .../scala/termware/ComputationBounds.scala | 9 +- src/main/scala/termware/PrimitiveTerm.scala | 10 ++- src/main/scala/termware/Substitution.scala | 82 +++++++++++++++---- src/main/scala/termware/Term.scala | 16 ++-- src/main/scala/termware/TermSignature.scala | 13 +++ 6 files changed, 103 insertions(+), 35 deletions(-) create mode 100644 src/main/scala/termware/TermSignature.scala diff --git a/build.sbt b/build.sbt index 1c6d3ec..448c515 100644 --- a/build.sbt +++ b/build.sbt @@ -3,19 +3,19 @@ name:="termware" organization:="com.github.termware" -scalaVersion := "2.10.0-M7" +scalaVersion := "2.10.0" scalacOptions ++= Seq("-unchecked","-deprecation","-feature") version:="0.0.2" -libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.0-M7" +libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.0" -libraryDependencies += "org.scala-lang" % "scala-actors" % "2.10.0-M7" +libraryDependencies += "org.scala-lang" % "scala-actors" % "2.10.0" // hack to support scalatest //libraryDependencies += "org.scalatest" %% "scalatest" % "1.9-2.10.0-M7-B1" % "test" -libraryDependencies += "org.scalatest" % "scalatest_2.10.0-M7" % "2.0.M4-2.10.0-M7-B1" +libraryDependencies += "org.scalatest" % "scalatest_2.10" % "1.9.1" % "test" diff --git a/src/main/scala/termware/ComputationBounds.scala b/src/main/scala/termware/ComputationBounds.scala index 90cf542..7dbddd1 100644 --- a/src/main/scala/termware/ComputationBounds.scala +++ b/src/main/scala/termware/ComputationBounds.scala @@ -79,11 +79,10 @@ case class Call[A]( thunk: (TrampolineId, Int) => ComputationBounds[A] ) extends ComputationBounds[A] { - def isDone: Boolean = false; - def result: Option[A] = None; - def step(tId:TrampolineId,depth:Int) = { - thunk(tId,depth); - } + def isDone: Boolean = false + def result: Option[A] = None + def step(tId:TrampolineId,depth:Int) = + thunk(tId,depth) } object Call diff --git a/src/main/scala/termware/PrimitiveTerm.scala b/src/main/scala/termware/PrimitiveTerm.scala index 0e2e687..6e68628 100644 --- a/src/main/scala/termware/PrimitiveTerm.scala +++ b/src/main/scala/termware/PrimitiveTerm.scala @@ -2,6 +2,7 @@ package termware import scala.reflect.runtime.universe._ import scala.math._ +import scala.util.{Try => UTry} abstract class PrimitiveToTerm[X:TypeTag](implicit ord:Ordering[X]) extends ToTerm[X] @@ -31,10 +32,17 @@ abstract class PrimitiveToTerm[X:TypeTag](implicit ord:Ordering[X]) extends ToTe def v(x:X):X = x + def subst(t:Term, s:Substitution): Term = + s.getOrElse(t,t) + + def unify(x:Term, y:Term): UTry[Substitution] = ??? + + + } -class NumericToTerm[X <% ScalaNumericConversions](implicit xtag:TypeTag[X], ord:Ordering[X]) extends PrimitiveToTerm[X] +class NumericToTerm[X <% ScalaNumericAnyConversions](implicit xtag:TypeTag[X], ord:Ordering[X]) extends PrimitiveToTerm[X] { override def isNumber(x:X) = true diff --git a/src/main/scala/termware/Substitution.scala b/src/main/scala/termware/Substitution.scala index b12ee89..df88d35 100644 --- a/src/main/scala/termware/Substitution.scala +++ b/src/main/scala/termware/Substitution.scala @@ -1,15 +1,32 @@ package termware; import scala.collection.immutable.TreeMap +import scala.util._ trait Substitution extends PartialFunction[Term,Term] { - def +(kv:(Term,Term)): (Boolean,Substitution) ; + def isEmpty: Boolean + + def get(k:Term): Option[Term] + + def getOrElse(k:Term, default: Term): Term = + get(k) match { + case Some(x) => x + case None => default + } + + def put(k:Term, v:Term): Try[Substitution] + + def merge(s: Substitution): Try[Substitution] def withIndex(newZipIndex:BigInt): Substitution - def lastZipIndex: BigInt; + def lastZipIndex: BigInt + + def foreach(f:((Term,Term)) => Unit): Unit + + def find(f:((Term,Term))=>Boolean): Option[(Term,Term)] } @@ -20,33 +37,68 @@ object STMSubstitution } -class STMSubstitution(val v: Map[Term,Pair[BigInt,Term]], +case class STMSubstitution(val map: Map[Term,Pair[BigInt,Term]], val lastZipIndex: BigInt) extends Substitution { + def withIndex(newZipIndex:BigInt):STMSubstitution = { val cmp = lastZipIndex.compare(newZipIndex); if (cmp > 0) - new STMSubstitution(v,newZipIndex) + new STMSubstitution(map,newZipIndex) else if (cmp < 0) new STMSubstitution( - v.filter({ _._2._1 < newZipIndex }),newZipIndex) + map.filter({ _._2._1 < newZipIndex }),newZipIndex) else /* newZipIndex == lastZipIndex */ this; } + + def get(k:Term) = map.get(k) map (_._2) - def +(kv:(Term,Term)): (Boolean,Substitution) = { - val r = v.get(kv._1); - val zkv = kv._1->Pair(lastZipIndex,kv._2); - if (r==None) - (true,new STMSubstitution(v+zkv,lastZipIndex)) - else - ??? - //r.get._2.unify(kv._2,new STMSubstitution(v+zkv,lastZipIndex)).get + def put(k:Term, v:Term): Try[Substitution] = { + map.get(k) match { + case None => Success(STMSubstitution(map.updated(k,(lastZipIndex,v)),lastZipIndex)) + case Some((v1,i1)) => + v.signature.unify(v,v1) flatMap (merge(_)) + } } - override def isDefinedAt(t:Term) = v.isDefinedAt(t); - override def apply(t:Term):Term = v.apply(t)._2; + + def merge(s:Substitution): Try[Substitution] = { + var l: List[Substitution] = s::Nil + var m = map + var optFailure: Option[Failure[Substitution]] = None + while(! l.isEmpty && optFailure.isEmpty) { + var c = l.head + l = l.tail + c.find { case (k,v) => + m.get(k) match { + case None => m = m.updated(k,(lastZipIndex,v)) + false + case Some((v1,z1)) => + v1.signature.unify(v1,v) match { + case f@Failure(ex) => optFailure = Some(f) + true + case Success(s1) => l = s1::l + false + } + } + } + } + optFailure.getOrElse(Success(STMSubstitution(m,lastZipIndex))) + } + + override def find(f:((Term,Term))=>Boolean): Option[(Term,Term)] = + map.mapValues(_._2).find(f) + + override def isEmpty = map.isEmpty + + override def isDefinedAt(t:Term) = map.isDefinedAt(t) + + override def apply(t:Term):Term = map(t)._2 + + override def foreach(f:((Term,Term))=>Unit) = map.mapValues(_._2).foreach(f) + } diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index c3120ff..2adc7ff 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -25,12 +25,11 @@ trait Term def value[T](implicit ttag:TypeTag[T]):Option[T] - def numberValue: Option[ScalaNumericConversions] + def numberValue: Option[ScalaNumericAnyConversions] def isX = false - //def subst(s:Substitution):ComputationBounds[Term] - + def signature: TermSignature } @@ -39,6 +38,7 @@ trait Term * typeclass for term algebra. */ abstract class ToTerm[X:TypeTag] + extends TermSignature { type Origin = X @@ -70,7 +70,7 @@ abstract class ToTerm[X:TypeTag] def value[T](x:X)(implicit ttag:TypeTag[T]):Option[T] - def numberValue(x:X): Option[ScalaNumericConversions] + def numberValue(x:X): Option[ScalaNumericAnyConversions] def isX(x:X):Boolean = false @@ -79,10 +79,6 @@ abstract class ToTerm[X:TypeTag] def toTerm(x:X):Term = new AsTerm(x,this) - //def subst(x:X):ComputationBounds[Term] - - //implicit def toTerm:ToTerm[X] = this; - } trait BaseAsTerm extends Term @@ -116,9 +112,9 @@ class AsTerm[X:TypeTag](x:X, tt: ToTerm[X]) extends BaseAsTerm def value[T](implicit ttag: TypeTag[T]): Option[T] = tt.value[T](x) - def numberValue: Option[ScalaNumericConversions] = tt.numberValue(x) - + def numberValue: Option[ScalaNumericAnyConversions] = tt.numberValue(x) + def signature = tt } diff --git a/src/main/scala/termware/TermSignature.scala b/src/main/scala/termware/TermSignature.scala new file mode 100644 index 0000000..fbf5b24 --- /dev/null +++ b/src/main/scala/termware/TermSignature.scala @@ -0,0 +1,13 @@ +package termware + +import scala.util._ + +trait TermSignature +{ + + def subst(t:Term, s:Substitution): Term + + def unify(x:Term, y:Term): Try[Substitution] + + +} From 2d2681f969baf8b1e09bb21e5b3155d0ee418188 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sun, 3 Mar 2013 15:00:40 +0200 Subject: [PATCH 05/27] more accurate tracking og UnificationResult --- src/main/scala/termware/PrimitiveTerm.scala | 17 +++-- src/main/scala/termware/Substitution.scala | 36 +++------- src/main/scala/termware/Term.scala | 72 ++++++++++++++----- src/main/scala/termware/TermSignature.scala | 13 ---- src/main/scala/termware/TermSystem.scala | 13 ++++ .../scala/termware/UnificationResult.scala | 39 ++++++++++ 6 files changed, 127 insertions(+), 63 deletions(-) delete mode 100644 src/main/scala/termware/TermSignature.scala create mode 100644 src/main/scala/termware/TermSystem.scala create mode 100644 src/main/scala/termware/UnificationResult.scala diff --git a/src/main/scala/termware/PrimitiveTerm.scala b/src/main/scala/termware/PrimitiveTerm.scala index 6e68628..3fdcc16 100644 --- a/src/main/scala/termware/PrimitiveTerm.scala +++ b/src/main/scala/termware/PrimitiveTerm.scala @@ -5,7 +5,7 @@ import scala.math._ import scala.util.{Try => UTry} -abstract class PrimitiveToTerm[X:TypeTag](implicit ord:Ordering[X]) extends ToTerm[X] +abstract class PrimitiveToTerm[X](implicit xtag: TypeTag[X], ord:Ordering[X]) extends ToTerm[X] { def name(x:X):Name = PrimitiveName[X](x) @@ -30,15 +30,22 @@ abstract class PrimitiveToTerm[X:TypeTag](implicit ord:Ordering[X]) extends ToTe None } - def v(x:X):X = x + type VType = X - def subst(t:Term, s:Substitution): Term = - s.getOrElse(t,t) + def vTag: TypeTag[X] = xtag - def unify(x:Term, y:Term): UTry[Substitution] = ??? + def v(x:X):X = x + def xunify(x: X, y: Term, s: Substitution): UnificationResult = ??? + def xsubstg(x: X, s: Substitution): Term = + { + val t = AsTerm[X](x,this) + s.getOrElse(t,t) + } + def xsubstv(x: X, s: Substitution): Term + = AsTerm[X](x, this) } diff --git a/src/main/scala/termware/Substitution.scala b/src/main/scala/termware/Substitution.scala index df88d35..f7d6c27 100644 --- a/src/main/scala/termware/Substitution.scala +++ b/src/main/scala/termware/Substitution.scala @@ -2,6 +2,8 @@ package termware; import scala.collection.immutable.TreeMap import scala.util._ +import scala.reflect.runtime.universe._ + trait Substitution extends PartialFunction[Term,Term] { @@ -16,9 +18,9 @@ trait Substitution extends PartialFunction[Term,Term] case None => default } - def put(k:Term, v:Term): Try[Substitution] + def put(k:Term, v:Term): UnificationResult - def merge(s: Substitution): Try[Substitution] + def merge(s: Substitution): UnificationResult def withIndex(newZipIndex:BigInt): Substitution @@ -55,37 +57,17 @@ case class STMSubstitution(val map: Map[Term,Pair[BigInt,Term]], def get(k:Term) = map.get(k) map (_._2) - def put(k:Term, v:Term): Try[Substitution] = { + def put(k:Term, v:Term): UnificationResult = { map.get(k) match { - case None => Success(STMSubstitution(map.updated(k,(lastZipIndex,v)),lastZipIndex)) + case None => UnificationSuccess(STMSubstitution(map.updated(k,(lastZipIndex,v)),lastZipIndex)) case Some((v1,i1)) => - v.signature.unify(v,v1) flatMap (merge(_)) + v.unify(v1, this) flatMap (merge(_)) } } - def merge(s:Substitution): Try[Substitution] = { - var l: List[Substitution] = s::Nil - var m = map - var optFailure: Option[Failure[Substitution]] = None - while(! l.isEmpty && optFailure.isEmpty) { - var c = l.head - l = l.tail - c.find { case (k,v) => - m.get(k) match { - case None => m = m.updated(k,(lastZipIndex,v)) - false - case Some((v1,z1)) => - v1.signature.unify(v1,v) match { - case f@Failure(ex) => optFailure = Some(f) - true - case Success(s1) => l = s1::l - false - } - } - } - } - optFailure.getOrElse(Success(STMSubstitution(m,lastZipIndex))) + def merge(s:Substitution): UnificationResult = { + ??? } override def find(f:((Term,Term))=>Boolean): Option[(Term,Term)] = diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 2adc7ff..a02e019 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -1,7 +1,8 @@ package termware -import scala.reflect.runtime.universe._ import scala.math._ +import scala.util._ +import scala.reflect.runtime.universe._ trait Term { @@ -27,9 +28,22 @@ trait Term def numberValue: Option[ScalaNumericAnyConversions] - def isX = false + def isX : Boolean + + /** + * unify self with term y + */ + def unify(y:Term, s: Substitution): UnificationResult + + /** + * generic substitution, where in right part can be any term + */ + def substg(s:Substitution): Term - def signature: TermSignature + /** + * substitution where in right part can be only variable definitions. + */ + def substv(s:Substitution): Term } @@ -38,7 +52,6 @@ trait Term * typeclass for term algebra. */ abstract class ToTerm[X:TypeTag] - extends TermSignature { type Origin = X @@ -79,6 +92,14 @@ abstract class ToTerm[X:TypeTag] def toTerm(x:X):Term = new AsTerm(x,this) + // signature part + + def xunify(x: X, y: Term, s: Substitution): UnificationResult + + def xsubstg(x: X, s: Substitution): Term + + def xsubstv(x: X, s: Substitution): Term + } trait BaseAsTerm extends Term @@ -87,38 +108,53 @@ trait BaseAsTerm extends Term type WrapperType <: ToTerm[ValueType]; } -class AsTerm[X:TypeTag](x:X, tt: ToTerm[X]) extends BaseAsTerm +case class AsTerm[V:TypeTag](v:V, tt: ToTerm[V]) extends BaseAsTerm { - type ValueType = X; + type ValueType = V; - def name:Name = tt.name(x) + def name:Name = tt.name(v) - def arity:Int = tt.arity(x) + def arity:Int = tt.arity(v) def subterms: IndexedSeq[Term] = - tt.subterms(x) + tt.subterms(v) def nameSubterms:Map[Name,Term] = - tt.nameSubterms(x) + tt.nameSubterms(v) - def isAtom: Boolean = tt.isAtom(x) + def isAtom: Boolean = tt.isAtom(v) - def isPrimitive: Boolean = tt.isPrimitive(x) + def isPrimitive: Boolean = tt.isPrimitive(v) - def isNumber: Boolean = tt.isNumber(x) + def isNumber: Boolean = tt.isNumber(v) - def is[T](implicit ttag: TypeTag[T]): Boolean = tt.is[T](x) + def is[T](implicit ttag: TypeTag[T]): Boolean = tt.is[T](v) - def value[T](implicit ttag: TypeTag[T]): Option[T] = tt.value[T](x) + def value[T](implicit ttag: TypeTag[T]): Option[T] = tt.value[T](v) - def numberValue: Option[ScalaNumericAnyConversions] = tt.numberValue(x) + def numberValue: Option[ScalaNumericAnyConversions] = tt.numberValue(v) - def signature = tt + def original: V = v -} + def isX: Boolean = false + + def unify(y: Term, s: Substitution): UnificationResult + = tt.xunify(v,y,s) + def substg(s:Substitution): Term + = tt.xsubstg(v, s) + def substv(s:Substitution): Term + = tt.xsubstv(v, s) + +} + +object AsTerm +{ + // can't use apply, because signature will be the same as in default case-class apply + def create[X](x:X)(implicit tt:ToTerm[X], ttag:TypeTag[X]) = new AsTerm(x, tt) +} // vim: set ts=4 sw=4 et: diff --git a/src/main/scala/termware/TermSignature.scala b/src/main/scala/termware/TermSignature.scala deleted file mode 100644 index fbf5b24..0000000 --- a/src/main/scala/termware/TermSignature.scala +++ /dev/null @@ -1,13 +0,0 @@ -package termware - -import scala.util._ - -trait TermSignature -{ - - def subst(t:Term, s:Substitution): Term - - def unify(x:Term, y:Term): Try[Substitution] - - -} diff --git a/src/main/scala/termware/TermSystem.scala b/src/main/scala/termware/TermSystem.scala new file mode 100644 index 0000000..71a4f4f --- /dev/null +++ b/src/main/scala/termware/TermSystem.scala @@ -0,0 +1,13 @@ +package termware + +import scala.reflect.runtime.universe._ + + + +trait TermSystem +{ + + def toTerm[T](t:T)(implicit ttag: TypeTag[T]): Term + + +} diff --git a/src/main/scala/termware/UnificationResult.scala b/src/main/scala/termware/UnificationResult.scala new file mode 100644 index 0000000..cefec47 --- /dev/null +++ b/src/main/scala/termware/UnificationResult.scala @@ -0,0 +1,39 @@ +package termware + + +sealed trait UnificationResult +{ + def isSuccess: Boolean + def isFailure: Boolean + + def toOption: Option[Substitution] + + def map(f: Substitution => Substitution): UnificationResult + + def flatMap(f: Substitution => UnificationResult): UnificationResult + +} + +case class UnificationSuccess(s:Substitution) extends UnificationResult +{ + @inline def isSuccess = true + @inline def isFailure = false + @inline def substitution = s + @inline def toOption: Option[Substitution] = Some(s) + @inline def map(f: Substitution => Substitution) = UnificationSuccess(f(s)) + @inline def flatMap(f: Substitution => UnificationResult): UnificationResult = f(s) + +} + +case class UnificationFailure(x:Term,y:Term,s:Substitution) extends UnificationResult +{ + @inline def isSuccess = false + @inline def isFailure = true + @inline def toOption: Option[Substitution] = None + @inline def map(f: Substitution => Substitution) = this + @inline def flatMap(f: Substitution => UnificationResult): UnificationResult = this + + +} + + From 7fc1afafcdfac17bce6f54ab52a9d69b619d025e Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Tue, 5 Mar 2013 07:53:07 +0200 Subject: [PATCH 06/27] implemented free complex term. --- doc/stermware.tex | 68 +++++++++++++++++++ project/plugins.sbt | 2 +- src/main/scala/termware/ComplexTerm.scala | 65 ++++++++++++++++++ src/main/scala/termware/FreeComplexTerm.scala | 57 ++++++++++++++++ src/main/scala/termware/PrimitiveTerm.scala | 6 +- src/main/scala/termware/Term.scala | 9 ++- src/main/scala/termware/TermSystem.scala | 5 +- 7 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 doc/stermware.tex create mode 100644 src/main/scala/termware/ComplexTerm.scala create mode 100644 src/main/scala/termware/FreeComplexTerm.scala diff --git a/doc/stermware.tex b/doc/stermware.tex new file mode 100644 index 0000000..d7dbdde --- /dev/null +++ b/doc/stermware.tex @@ -0,0 +1,68 @@ +\title{STermWare: brief semantics description} +\author{ + Ruslan Shevchenko \\ + ruslan@shevchenko.kiev.ua\\ + Kiev, Ukraine +} +\date{\today} + + + +\documentclass[12pt]{article} +\usepackage{listings} + +% "define" Scala +\lstdefinelanguage{scala}{ + morekeywords={abstract,case,catch,class,def,% + do,else,extends,false,final,finally,% + for,if,implicit,import,match,mixin,% + new,null,object,override,package,% + private,protected,requires,return,sealed,% + super,this,throw,trait,true,try,% + type,val,var,while,with,yield}, + otherkeywords={=>,<-,<\%,<:,>:,\#,@}, + sensitive=true, + morecomment=[l]{//}, + morecomment=[n]{/*}{*/}, + morestring=[b]", + morestring=[b]', + morestring=[b]""" +} + + + +\begin{document} +\maketitle + +\begin{abstract} + Termware is a term rewriting system which implemented as internal and external DSL. +\end{abstract} + +\section{Motivation} + + Rule-based deduction and rewriting is well known + + Let we have some big structure with some semantics, which can be expressed as expression in some DSL (in case of source code + analysis -- analysed language) + + Rule rewriting allow to discover patternsm + +\section{Basic definitions} + + Let's build term algebra on top of some set of constants, whuch constists from +\begin{itemize} + \item original constants ${c_i} \in C$ Also we + will need to distinguish some special subset of constants: atoms ${a_i}$ + \item functional term $f_i \in F$ i.e. if $f \in F, c_i \in C (i \in 1..n)$, then $f(c_{1} \dots c_{n}) \in T$ + \item variable terms $x_{i}$ which can be inside variable-bound terms. + \item variable bounds term, i.e. so-called 'with-expressions': $with(x_1,\dots x_n):t$ + \item let terms, i.e. so-called 'let expressions' $let \{ x_i \leftarrow t_i \}_{1\dots n} t \in T$ + \item rule terms, i. e. so-called 'rule expressions': $ruleset(p_1 \to r_1 ; p_2 \to r_2; .. p_n => r_n)$ +\end{itemize} + + + +\bibliographystyle{abbrv} +\bibliography{stermware} + +\end{document} diff --git a/project/plugins.sbt b/project/plugins.sbt index f43936d..aba5098 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += Classpaths.typesafeResolver -//addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0") diff --git a/src/main/scala/termware/ComplexTerm.scala b/src/main/scala/termware/ComplexTerm.scala new file mode 100644 index 0000000..f6f301b --- /dev/null +++ b/src/main/scala/termware/ComplexTerm.scala @@ -0,0 +1,65 @@ +package termware + +import scala.reflect.runtime.universe._ +import scala.math._ + +trait ComplexTerm extends Term +{ + + def isAtom:Boolean = false + + def isPrimitive:Boolean = false + + def isNumber: Boolean = false + + def isComplex: Boolean = true + + // withoyut default mapping to laguage objects. + def is[T](implicit ttag:TypeTag[T]):Boolean = false + + def value[T](implicit ttag:TypeTag[T]):Option[T] = None + + def numberValue: Option[ScalaNumericAnyConversions] = None + + def isX : Boolean = false + + + +} + + +abstract class ComplexToTerm[X](implicit xtag: TypeTag[X], ord:Ordering[X]) extends ToTerm[X] +{ + + def name(x:X):Name + + def arity(x:X):Int + + def subterms(x:X):IndexedSeq[BaseAsTerm] + + def nameSubterms(x:X):Map[Name,BaseAsTerm] + + def isAtom(x:X) = false + + def isPrimitive(x:X) = false + + def is[T](x:X)(implicit ttag:TypeTag[T]):Boolean = + (typeOf[T] <:< typeOf[X]) + + def value[T](t:X)(implicit ttag:TypeTag[T]):Option[T] = + if (typeOf[T] <:< typeOf[X]) { + Some(t.asInstanceOf[T]) + } else { + None + } + + type VType = X + + def vTag: TypeTag[X] = xtag + + def v(x:X):X = x + + +} + +// vim: set ts=4 sw=4 et: diff --git a/src/main/scala/termware/FreeComplexTerm.scala b/src/main/scala/termware/FreeComplexTerm.scala new file mode 100644 index 0000000..2989066 --- /dev/null +++ b/src/main/scala/termware/FreeComplexTerm.scala @@ -0,0 +1,57 @@ +package termware + +import scala.math._ +import scala.reflect.runtime.universe._ + +case class FreeComplexTerm(val name: Name, + val subterms: IndexedSeq[Term] + )extends ComplexTerm { + + + def arity: Int = subterms.length + + + /** + * unify self with term y + */ + // TODO: add nesting parameter and swith to computatio bounds if one is big. + def unify(y:Term, s0: Substitution): UnificationResult = + if (y.arity != arity) + UnificationFailure(this,y,s0) + else { + var quit = false + var n = arity + var i =0 + var s = s0 + var r: UnificationResult = UnificationSuccess(s) + while( i < arity && !quit) { + val cx = subterm(i).get + val cy = y.subterm(i).get + i += 1 + r = cx.unify(cy,s0) + r match { + case UnificationSuccess(substitution) => + s = substitution + case UnificationFailure(x,y,substitution) => + quit = true + } + } + r + } + + + + /** + * generic substitution, where in right part can be any term + */ + def substg(s:Substitution): Term = + FreeComplexTerm(name,subterms map (_.substg(s))) + + /** + * substitution where in right part can be only variable definitions. + */ + def substv(s: Substitution): Term = + FreeComplexTerm(name, subterms map (_.substv(s))) + + +} \ No newline at end of file diff --git a/src/main/scala/termware/PrimitiveTerm.scala b/src/main/scala/termware/PrimitiveTerm.scala index 3fdcc16..1b11068 100644 --- a/src/main/scala/termware/PrimitiveTerm.scala +++ b/src/main/scala/termware/PrimitiveTerm.scala @@ -16,9 +16,11 @@ abstract class PrimitiveToTerm[X](implicit xtag: TypeTag[X], ord:Ordering[X]) ex def nameSubterms(x:X):Map[Name,BaseAsTerm] = Map() - def isAtom(x:X) = false + @inline def isAtom(x:X) = false - def isPrimitive(x:X) = true + @inline def isPrimitive(x:X) = true + + @inline def isComplex(x:X) = false def is[T](x:X)(implicit ttag:TypeTag[T]):Boolean = (typeOf[T] <:< typeOf[X]) diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index a02e019..b22adb9 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -22,13 +22,16 @@ trait Term def isNumber: Boolean; + def isX : Boolean + + def isComplex: Boolean + def is[T](implicit ttag:TypeTag[T]):Boolean def value[T](implicit ttag:TypeTag[T]):Option[T] def numberValue: Option[ScalaNumericAnyConversions] - def isX : Boolean /** * unify self with term y @@ -78,6 +81,8 @@ abstract class ToTerm[X:TypeTag] def isPrimitive(x:X):Boolean; def isNumber(x:X):Boolean; + + def isComplex(x:X): Boolean; def is[T](x:X)(implicit ttag:TypeTag[T]):Boolean @@ -138,6 +143,8 @@ case class AsTerm[V:TypeTag](v:V, tt: ToTerm[V]) extends BaseAsTerm def original: V = v def isX: Boolean = false + + def isComplex: Boolean = tt.isComplex(v) def unify(y: Term, s: Substitution): UnificationResult = tt.xunify(v,y,s) diff --git a/src/main/scala/termware/TermSystem.scala b/src/main/scala/termware/TermSystem.scala index 71a4f4f..fbac4b1 100644 --- a/src/main/scala/termware/TermSystem.scala +++ b/src/main/scala/termware/TermSystem.scala @@ -7,7 +7,8 @@ import scala.reflect.runtime.universe._ trait TermSystem { - def toTerm[T](t:T)(implicit ttag: TypeTag[T]): Term - + def toTerm[T](t:T)(implicit ttag: TypeTag[T]): Either[String,Term] + + def fromTerm[T](t: Term)(implicit ttag: TypeTag[T]): Either[String,T] } From 812714131697d3cbc0a5216551b8501b05001afe Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 16 Mar 2013 16:38:27 +0200 Subject: [PATCH 07/27] added constructro fro FreeCompleTerm --- src/main/scala/termware/AtomTerm.scala | 110 ++++++++++++++++++ src/main/scala/termware/package.scala | 10 +- .../scala/termware/BaseTermFunSuite.scala | 14 ++- .../termware/FreeCompleTermFunSuite.scala | 29 +++++ 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 src/main/scala/termware/AtomTerm.scala create mode 100644 src/test/scala/termware/FreeCompleTermFunSuite.scala diff --git a/src/main/scala/termware/AtomTerm.scala b/src/main/scala/termware/AtomTerm.scala new file mode 100644 index 0000000..78e06e3 --- /dev/null +++ b/src/main/scala/termware/AtomTerm.scala @@ -0,0 +1,110 @@ +package termware + +import scala.language.implicitConversions +import scala.reflect.runtime.universe.TypeTag +import scala.reflect.runtime.universe.typeOf +import scala.math.ScalaNumericAnyConversions + +object AtomToTerm extends ToTerm[Symbol] +{ + + def name(x:Symbol):Name = SymbolName(x) + + def arity(x:Symbol):Int = 0 + + def subterms(x:Symbol):IndexedSeq[BaseAsTerm] = IndexedSeq() + + override def subterm(x: Symbol,i:Int): Option[BaseAsTerm] = None + + def nameSubterms(x:Symbol):Map[Name,BaseAsTerm] = Map() + + def isAtom(x:Symbol):Boolean = true + + def isPrimitive(x:Symbol):Boolean = false + + def isNumber(x:Symbol):Boolean = false + + def isComplex(x:Symbol): Boolean = false + + def is[T](x:Symbol)(implicit ttag:TypeTag[T]):Boolean = + typeOf[T] <:< typeOf[Symbol] + + def value[T](x:Symbol)(implicit ttag:TypeTag[T]):Option[T] = + if (typeOf[T] <:< typeOf[Symbol]) { + Some(x.asInstanceOf[T]) + } else { + None + } + + def numberValue(x:Symbol): Option[ScalaNumericAnyConversions] = None + + + override def toTerm(x:Symbol):Term = + AtomTerm(x) + + // signature part + + def xunify(x: Symbol, y: Term, s: Substitution): UnificationResult = + if (y.isAtom) { + y.name match { + case SymbolName(n) if n == x => UnificationSuccess(s) + case _ => UnificationFailure(x,y,s) + } + } else { + UnificationFailure(x,y,s) + } + + + def xsubstg(x: Symbol, s: Substitution): Term = ??? + + def xsubstv(x: Symbol, s: Substitution): Term = ??? + + +} + +case class AtomTerm(a:Symbol) extends Term { + + val name = SymbolName(a) + + def arity: Int = 0 + + def subterms:IndexedSeq[Term] = IndexedSeq() + + override def subterm(i:Int): Option[Term] = None + + def isAtom:Boolean = true + + def isPrimitive:Boolean = false + + def isNumber: Boolean = false + + def isX : Boolean = false + + def isComplex: Boolean = false + + def is[T](implicit ttag:TypeTag[T]):Boolean = + (typeOf[T] <:< typeOf[Symbol]) + + def value[T](implicit ttag:TypeTag[T]):Option[T] = + if (typeOf[T] <:< typeOf[Symbol]) Some(a.asInstanceOf[T]) else None + + def numberValue = None + + def unify(y:Term, s: Substitution): UnificationResult = + if (y.isAtom && name == y.name) UnificationSuccess(s) else UnificationFailure(this,y,s) + + def substg(s:Substitution): Term = s.get(this).getOrElse(this) + + def substv(s:Substitution): Term = this + + +} + +object AtomTerm +{ + + // implicit def toAtom(s: Symbol) = AtomTerm(s) + + def unapply(s: Symbol) = AtomTerm(s) + +} \ No newline at end of file diff --git a/src/main/scala/termware/package.scala b/src/main/scala/termware/package.scala index 5eb590e..0dae596 100644 --- a/src/main/scala/termware/package.scala +++ b/src/main/scala/termware/package.scala @@ -1,6 +1,6 @@ import language.implicitConversions -import scala.reflect.runtime.universe._ +import scala.reflect.runtime.universe.TypeTag package object termware { @@ -18,7 +18,15 @@ package object termware { implicit val stringToTerm = new NonNumericPrimitiveToTerm[String] + implicit val atomTerm = AtomToTerm implicit val termOrdering: Ordering[Term] = TermOrdering + @inline + implicit class TermSymbolApply(s: Symbol) + { + def apply(args:Term*): Term = + new FreeComplexTerm(SymbolName(s),args.toIndexedSeq) + } + } diff --git a/src/test/scala/termware/BaseTermFunSuite.scala b/src/test/scala/termware/BaseTermFunSuite.scala index d2c6628..0e738df 100644 --- a/src/test/scala/termware/BaseTermFunSuite.scala +++ b/src/test/scala/termware/BaseTermFunSuite.scala @@ -26,8 +26,20 @@ class BaseTermFunSuite extends FunSuite t.isNumber should be(true) t.numberValue.get.intValue() should be(5) } + + test("string term") { + val t: Term = "AAA" + t.arity should be(0) + t.is[String] should be(true) + t.value[String] should be(Some("AAA")) + } - + test("atom term") { + val t:Term = 'a + t.arity should be(0) + t.isAtom should be(true) + } + } diff --git a/src/test/scala/termware/FreeCompleTermFunSuite.scala b/src/test/scala/termware/FreeCompleTermFunSuite.scala new file mode 100644 index 0000000..254c1a9 --- /dev/null +++ b/src/test/scala/termware/FreeCompleTermFunSuite.scala @@ -0,0 +1,29 @@ +package termware + +import org.scalatest.FunSuite + +class FreeCompleTermFunSuite extends FunSuite + // note, that ShoultMatchers conflicts with free term constructor +{ + + test("free complex term") { + val t: Term = 'f(1,'g(3),3,"AAA") + assert(t.arity==4) + val f0 = t.subterms(0) + assert(f0.is[Int]) + val f1 = t.subterms(1) + assert(f1.isComplex) + assert(f1.arity==1) + /* + t match { + case Term('f,args) => args(0) should be equal(f0) + } + */ + + } + + +} + + +// vim: set ts=4 sw=4 et: From 723aebae0951f9c770d0fd4b9f635b5f38d43fee Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 16 Mar 2013 21:13:23 +0200 Subject: [PATCH 08/27] added mapping from case classes to terms --- src/main/scala/termware/CaseClassTerm.scala | 43 +++++++++++++ src/main/scala/termware/ComplexTerm.scala | 6 +- src/main/scala/termware/Reflect.scala | 60 +++++++++++++++++++ src/main/scala/termware/Term.scala | 8 +-- .../scala/termware/UnificationResult.scala | 2 - src/main/scala/termware/package.scala | 7 ++- 6 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 src/main/scala/termware/CaseClassTerm.scala create mode 100644 src/main/scala/termware/Reflect.scala diff --git a/src/main/scala/termware/CaseClassTerm.scala b/src/main/scala/termware/CaseClassTerm.scala new file mode 100644 index 0000000..a12b1c6 --- /dev/null +++ b/src/main/scala/termware/CaseClassTerm.scala @@ -0,0 +1,43 @@ +package termware + +import scala.reflect._ +import scala.reflect.runtime.universe._ + +class CaseClassToTerm[X <: AnyRef with Product](implicit xtag:TypeTag[X]) extends ComplexToTerm[X] +{ + + lazy val fixedName = SymbolName(Symbol(xtag.tpe.typeSymbol.asClass.name.toString())) + + def name(x:X) = fixedName + + // Members declared in termware.ComplexToTerm + def arity(x: X): Int = x.productArity + + def nameSubterms(x: X): Map[Name, Term] = + fixedNameSubterms + + def fixedNameSubterms: Map[Name, Term] = ??? + + def subterms(x: X): IndexedSeq[Term] = + Reflect.caseClassSubterms(x,xtag) + + def isComplex(x:X): Boolean = x.productArity > 0 + + def isNumber(x: X): Boolean = false + + def numberValue(x: X): Option[scala.math.ScalaNumericAnyConversions] = None + + def xsubstg(x: X,s: termware.Substitution): termware.Term = ??? + + def xsubstv(x: X,s: termware.Substitution): termware.Term = { + new AsTerm(x,this) + } + + def xunify(x: X,y: termware.Term,s: termware.Substitution): termware.UnificationResult = ??? + + +} + + + + diff --git a/src/main/scala/termware/ComplexTerm.scala b/src/main/scala/termware/ComplexTerm.scala index f6f301b..5f1d826 100644 --- a/src/main/scala/termware/ComplexTerm.scala +++ b/src/main/scala/termware/ComplexTerm.scala @@ -28,16 +28,16 @@ trait ComplexTerm extends Term } -abstract class ComplexToTerm[X](implicit xtag: TypeTag[X], ord:Ordering[X]) extends ToTerm[X] +abstract class ComplexToTerm[X](implicit xtag: TypeTag[X]) extends ToTerm[X] { def name(x:X):Name def arity(x:X):Int - def subterms(x:X):IndexedSeq[BaseAsTerm] + def subterms(x:X):IndexedSeq[Term] - def nameSubterms(x:X):Map[Name,BaseAsTerm] + def nameSubterms(x:X):Map[Name,Term] def isAtom(x:X) = false diff --git a/src/main/scala/termware/Reflect.scala b/src/main/scala/termware/Reflect.scala new file mode 100644 index 0000000..2c2ffbd --- /dev/null +++ b/src/main/scala/termware/Reflect.scala @@ -0,0 +1,60 @@ +package termware + +import scala.reflect.runtime.universe._ + +/** + * reconstruct mapping from scala object to terms, as in default system + */ +object Reflect { + + def caseClassSubterms[X <: AnyRef with Product](x:X, xtag: TypeTag[X]): IndexedSeq[Term] = + { + ??? + } + + @specialized + def asTerm[X](x:X, xtag: TypeTag[X]): Term = + { + val ts = xtag.tpe.typeSymbol + if (ts.isClass) { + val cs = ts.asClass + if (cs.isPrimitive) { + if (cs.isNumeric) { + if (xtag.tpe =:= typeOf[Long]) { + AsTerm.create[Long](x.asInstanceOf[Long]) + } else if (xtag.tpe =:= typeOf[Int]) { + AsTerm.create[Int](x.asInstanceOf[Int]) + } else if (xtag.tpe =:= typeOf[Float]) { + AsTerm.create[Float](x.asInstanceOf[Float]) + } else { + ??? + } + } else if (xtag.tpe =:= typeOf[Char]) { + AsTerm.create[Char](x.asInstanceOf[Char]) + } else if (xtag.tpe =:= typeOf[Boolean]) { + AsTerm.create[Boolean](x.asInstanceOf[Boolean]) + } else if (xtag.tpe =:= typeOf[Unit]) { + /// AsTerm.create[Unit](()) + ??? + } else { + throw new IllegalArgumentException("Unknown primitive:"+cs) + } + } else if (cs.isCaseClass) { + val xxtag = xtag.asInstanceOf[TypeTag[({ type Y <: AnyRef with Product })#Y ]] + val cct = new CaseClassToTerm[({ type Y <: AnyRef with Product })#Y]()(xxtag) + new AsTerm(x.asInstanceOf[({ type Y <: AnyRef with Product })#Y], cct)(xxtag) + } else if (xtag.tpe =:= typeOf[String]) { + AsTerm.create[String](x.asInstanceOf[String]) + } else { + ??? + // TODO: AnyRef term. + } + } else if (ts.isErroneous) { + ??? + } else { + ??? + } + } + + +} \ No newline at end of file diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index b22adb9..ccaa0b5 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -63,17 +63,17 @@ abstract class ToTerm[X:TypeTag] def arity(x:X):Int - def subterms(x:X):IndexedSeq[BaseAsTerm] + def subterms(x:X):IndexedSeq[Term] - def subterm(x:X,i:Int): Option[BaseAsTerm] = + def subterm(x:X,i:Int): Option[Term] = if (i Substitution) = this @inline def flatMap(f: Substitution => UnificationResult): UnificationResult = this - - } diff --git a/src/main/scala/termware/package.scala b/src/main/scala/termware/package.scala index 0dae596..1c58f2b 100644 --- a/src/main/scala/termware/package.scala +++ b/src/main/scala/termware/package.scala @@ -17,11 +17,16 @@ package object termware { implicit val bigIntToTerm = new NumericToTerm[BigInt] implicit val stringToTerm = new NonNumericPrimitiveToTerm[String] - + implicit val charToTerm = new NonNumericPrimitiveToTerm[Char] + implicit val booleanToTerm = new NonNumericPrimitiveToTerm[Boolean] + + implicit val atomTerm = AtomToTerm implicit val termOrdering: Ordering[Term] = TermOrdering + + @inline implicit class TermSymbolApply(s: Symbol) { From 56d2d4202c0fad55a095959ee27abab279d9ac94 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Wed, 23 Oct 2013 21:10:46 +0300 Subject: [PATCH 09/27] updated eclipse plugin version --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index aba5098..0d469ac 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += Classpaths.typesafeResolver -addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.3.0") From 7717e18f4420a2e2419c97a762f81b21e9d35fbf Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sun, 20 Jul 2014 16:57:37 +0300 Subject: [PATCH 10/27] ported to scala-2.11.0 --- build.sbt | 5 ++--- src/main/scala/termware/ComputationBounds.scala | 6 +++--- src/main/scala/termware/Reflect.scala | 4 +--- src/main/scala/termware/Substitution.scala | 4 ++-- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/build.sbt b/build.sbt index 448c515..f9f326d 100644 --- a/build.sbt +++ b/build.sbt @@ -3,15 +3,14 @@ name:="termware" organization:="com.github.termware" -scalaVersion := "2.10.0" +scalaVersion := "2.11.0" scalacOptions ++= Seq("-unchecked","-deprecation","-feature") version:="0.0.2" -libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.0" +libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.11.0" -libraryDependencies += "org.scala-lang" % "scala-actors" % "2.10.0" // hack to support scalatest //libraryDependencies += "org.scalatest" %% "scalatest" % "1.9-2.10.0-M7-B1" % "test" diff --git a/src/main/scala/termware/ComputationBounds.scala b/src/main/scala/termware/ComputationBounds.scala index 7dbddd1..7cd44cf 100644 --- a/src/main/scala/termware/ComputationBounds.scala +++ b/src/main/scala/termware/ComputationBounds.scala @@ -29,7 +29,7 @@ sealed abstract class ComputationBounds[+A] def toFuture(implicit executor:ExecutionContext): Future[A] = - future{ trampoline(this); } + Future{ trampoline(this); } // Monadic syntax @@ -186,8 +186,8 @@ object ComputationBounds sealed trait Cont[A,+B] { - type From = A; - type To = B; + //type From = A; + //type To = B; } case class ContOne[A,B](f: (TrampolineId,Int,A)=> ComputationBounds[B], n: Int = 0) extends Cont[A,B] diff --git a/src/main/scala/termware/Reflect.scala b/src/main/scala/termware/Reflect.scala index 2c2ffbd..359b751 100644 --- a/src/main/scala/termware/Reflect.scala +++ b/src/main/scala/termware/Reflect.scala @@ -49,12 +49,10 @@ object Reflect { ??? // TODO: AnyRef term. } - } else if (ts.isErroneous) { - ??? } else { ??? } } -} \ No newline at end of file +} diff --git a/src/main/scala/termware/Substitution.scala b/src/main/scala/termware/Substitution.scala index f7d6c27..cbb23a4 100644 --- a/src/main/scala/termware/Substitution.scala +++ b/src/main/scala/termware/Substitution.scala @@ -35,11 +35,11 @@ trait Substitution extends PartialFunction[Term,Term] object STMSubstitution { - def empty = new STMSubstitution(TreeMap[Term,Pair[BigInt,Term]](),BigInt(1)); + def empty = new STMSubstitution(TreeMap[Term,Tuple2[BigInt,Term]](),BigInt(1)); } -case class STMSubstitution(val map: Map[Term,Pair[BigInt,Term]], +case class STMSubstitution(val map: Map[Term,Tuple2[BigInt,Term]], val lastZipIndex: BigInt) extends Substitution { From c026ce98c9cd696d7b248842ef6182e110abe086 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Wed, 31 Dec 2014 20:26:36 +0200 Subject: [PATCH 11/27] scalaVersion-depended reflect in build.sbt --- build.sbt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/build.sbt b/build.sbt index f9f326d..d1acfdc 100644 --- a/build.sbt +++ b/build.sbt @@ -3,18 +3,15 @@ name:="termware" organization:="com.github.termware" -scalaVersion := "2.11.0" +scalaVersion := "2.11.4" scalacOptions ++= Seq("-unchecked","-deprecation","-feature") version:="0.0.2" -libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.11.0" +libraryDependencies <+= (scalaVersion){ "org.scala-lang" % "scala-reflect" % _ } - -// hack to support scalatest -//libraryDependencies += "org.scalatest" %% "scalatest" % "1.9-2.10.0-M7-B1" % "test" -libraryDependencies += "org.scalatest" % "scalatest_2.10" % "1.9.1" % "test" +libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.1" % "test" From 526f1fa82e743e2fd0d659e3daef86798ba9d4ab Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sun, 20 Sep 2015 18:04:05 +0300 Subject: [PATCH 12/27] mininal compiled set. --- build.sbt | 2 +- src/main/scala/termware/AtomTerm.scala | 110 -------- src/main/scala/termware/AtomTermOps.scala | 12 + .../scala/termware/AttributedTermOps.scala | 24 ++ src/main/scala/termware/CallCCThrowable.scala | 12 - src/main/scala/termware/CaseClassTerm.scala | 43 --- src/main/scala/termware/CharTermOps.scala | 7 + src/main/scala/termware/ComplexTerm.scala | 65 ----- .../scala/termware/ComputationBounds.scala | 258 ------------------ src/main/scala/termware/DoubleTermOps.scala | 7 + src/main/scala/termware/FreeComplexTerm.scala | 57 ---- src/main/scala/termware/FreeTermSystem.scala | 13 + src/main/scala/termware/FreeVarTermOps.scala | 10 + src/main/scala/termware/Int32TermOps.scala | 7 + src/main/scala/termware/Int64TermOps.scala | 7 + src/main/scala/termware/Name.scala | 148 ++++++---- src/main/scala/termware/NumericTermOps.scala | 7 + src/main/scala/termware/OpaqueTermOps.scala | 9 + src/main/scala/termware/PrimitiveTerm.scala | 90 ------ .../scala/termware/PrimitiveTermOps.scala | 18 ++ src/main/scala/termware/Reflect.scala | 58 ---- src/main/scala/termware/StringTermOps.scala | 9 + .../scala/termware/StructuredTermOps.scala | 23 ++ src/main/scala/termware/Substitution.scala | 87 ------ src/main/scala/termware/Term.scala | 183 ++++--------- src/main/scala/termware/TermAttributes.scala | 11 + .../scala/termware/TermEmptyComponents.scala | 18 ++ src/main/scala/termware/TermOps.scala | 25 ++ src/main/scala/termware/TermOrdering.scala | 35 --- src/main/scala/termware/TermStructure.scala | 17 ++ src/main/scala/termware/TermSystem.scala | 8 +- src/main/scala/termware/TrampolineId.scala | 20 -- .../scala/termware/UnattributedTermOps.scala | 14 + .../scala/termware/UnificationResult.scala | 37 --- src/main/scala/termware/package.scala | 37 --- .../scala/termware/BaseTermFunSuite.scala | 47 ---- .../termware/ComputationBoundsFunSuite.scala | 73 ----- .../termware/FreeCompleTermFunSuite.scala | 29 -- 38 files changed, 389 insertions(+), 1248 deletions(-) delete mode 100644 src/main/scala/termware/AtomTerm.scala create mode 100644 src/main/scala/termware/AtomTermOps.scala create mode 100644 src/main/scala/termware/AttributedTermOps.scala delete mode 100644 src/main/scala/termware/CallCCThrowable.scala delete mode 100644 src/main/scala/termware/CaseClassTerm.scala create mode 100644 src/main/scala/termware/CharTermOps.scala delete mode 100644 src/main/scala/termware/ComplexTerm.scala delete mode 100644 src/main/scala/termware/ComputationBounds.scala create mode 100644 src/main/scala/termware/DoubleTermOps.scala delete mode 100644 src/main/scala/termware/FreeComplexTerm.scala create mode 100644 src/main/scala/termware/FreeTermSystem.scala create mode 100644 src/main/scala/termware/FreeVarTermOps.scala create mode 100644 src/main/scala/termware/Int32TermOps.scala create mode 100644 src/main/scala/termware/Int64TermOps.scala create mode 100644 src/main/scala/termware/NumericTermOps.scala create mode 100644 src/main/scala/termware/OpaqueTermOps.scala delete mode 100644 src/main/scala/termware/PrimitiveTerm.scala create mode 100644 src/main/scala/termware/PrimitiveTermOps.scala delete mode 100644 src/main/scala/termware/Reflect.scala create mode 100644 src/main/scala/termware/StringTermOps.scala create mode 100644 src/main/scala/termware/StructuredTermOps.scala delete mode 100644 src/main/scala/termware/Substitution.scala create mode 100644 src/main/scala/termware/TermAttributes.scala create mode 100644 src/main/scala/termware/TermEmptyComponents.scala create mode 100644 src/main/scala/termware/TermOps.scala delete mode 100644 src/main/scala/termware/TermOrdering.scala create mode 100644 src/main/scala/termware/TermStructure.scala delete mode 100644 src/main/scala/termware/TrampolineId.scala create mode 100644 src/main/scala/termware/UnattributedTermOps.scala delete mode 100644 src/main/scala/termware/UnificationResult.scala delete mode 100644 src/main/scala/termware/package.scala delete mode 100644 src/test/scala/termware/BaseTermFunSuite.scala delete mode 100644 src/test/scala/termware/ComputationBoundsFunSuite.scala delete mode 100644 src/test/scala/termware/FreeCompleTermFunSuite.scala diff --git a/build.sbt b/build.sbt index d1acfdc..97efec7 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ name:="termware" organization:="com.github.termware" -scalaVersion := "2.11.4" +scalaVersion := "2.11.7" scalacOptions ++= Seq("-unchecked","-deprecation","-feature") diff --git a/src/main/scala/termware/AtomTerm.scala b/src/main/scala/termware/AtomTerm.scala deleted file mode 100644 index 78e06e3..0000000 --- a/src/main/scala/termware/AtomTerm.scala +++ /dev/null @@ -1,110 +0,0 @@ -package termware - -import scala.language.implicitConversions -import scala.reflect.runtime.universe.TypeTag -import scala.reflect.runtime.universe.typeOf -import scala.math.ScalaNumericAnyConversions - -object AtomToTerm extends ToTerm[Symbol] -{ - - def name(x:Symbol):Name = SymbolName(x) - - def arity(x:Symbol):Int = 0 - - def subterms(x:Symbol):IndexedSeq[BaseAsTerm] = IndexedSeq() - - override def subterm(x: Symbol,i:Int): Option[BaseAsTerm] = None - - def nameSubterms(x:Symbol):Map[Name,BaseAsTerm] = Map() - - def isAtom(x:Symbol):Boolean = true - - def isPrimitive(x:Symbol):Boolean = false - - def isNumber(x:Symbol):Boolean = false - - def isComplex(x:Symbol): Boolean = false - - def is[T](x:Symbol)(implicit ttag:TypeTag[T]):Boolean = - typeOf[T] <:< typeOf[Symbol] - - def value[T](x:Symbol)(implicit ttag:TypeTag[T]):Option[T] = - if (typeOf[T] <:< typeOf[Symbol]) { - Some(x.asInstanceOf[T]) - } else { - None - } - - def numberValue(x:Symbol): Option[ScalaNumericAnyConversions] = None - - - override def toTerm(x:Symbol):Term = - AtomTerm(x) - - // signature part - - def xunify(x: Symbol, y: Term, s: Substitution): UnificationResult = - if (y.isAtom) { - y.name match { - case SymbolName(n) if n == x => UnificationSuccess(s) - case _ => UnificationFailure(x,y,s) - } - } else { - UnificationFailure(x,y,s) - } - - - def xsubstg(x: Symbol, s: Substitution): Term = ??? - - def xsubstv(x: Symbol, s: Substitution): Term = ??? - - -} - -case class AtomTerm(a:Symbol) extends Term { - - val name = SymbolName(a) - - def arity: Int = 0 - - def subterms:IndexedSeq[Term] = IndexedSeq() - - override def subterm(i:Int): Option[Term] = None - - def isAtom:Boolean = true - - def isPrimitive:Boolean = false - - def isNumber: Boolean = false - - def isX : Boolean = false - - def isComplex: Boolean = false - - def is[T](implicit ttag:TypeTag[T]):Boolean = - (typeOf[T] <:< typeOf[Symbol]) - - def value[T](implicit ttag:TypeTag[T]):Option[T] = - if (typeOf[T] <:< typeOf[Symbol]) Some(a.asInstanceOf[T]) else None - - def numberValue = None - - def unify(y:Term, s: Substitution): UnificationResult = - if (y.isAtom && name == y.name) UnificationSuccess(s) else UnificationFailure(this,y,s) - - def substg(s:Substitution): Term = s.get(this).getOrElse(this) - - def substv(s:Substitution): Term = this - - -} - -object AtomTerm -{ - - // implicit def toAtom(s: Symbol) = AtomTerm(s) - - def unapply(s: Symbol) = AtomTerm(s) - -} \ No newline at end of file diff --git a/src/main/scala/termware/AtomTermOps.scala b/src/main/scala/termware/AtomTermOps.scala new file mode 100644 index 0000000..29431d7 --- /dev/null +++ b/src/main/scala/termware/AtomTermOps.scala @@ -0,0 +1,12 @@ +package termware + + +trait AtomTermOps extends TermEmptyComponents with UnattributedTermOps +{ + + this: AtomTerm => + + def isFreeVar = false + +} + diff --git a/src/main/scala/termware/AttributedTermOps.scala b/src/main/scala/termware/AttributedTermOps.scala new file mode 100644 index 0000000..3164596 --- /dev/null +++ b/src/main/scala/termware/AttributedTermOps.scala @@ -0,0 +1,24 @@ +package termware + +trait AttributedTermOps +{ + this: AttributedTerm => + + def name: Name = unattributed.name + + def arity: Int = unattributed.arity + + def componentNames: IndexedSeq[Name] = + unattributed.componentNames + + def component(i: Int): Option[Term] = + unattributed.component(i) + + def component(n: Name): Option[Term] = + unattributed.component(n) + + def isAttributed: Boolean = true + + def isFreeVar: Boolean = unattributed.isFreeVar + +} diff --git a/src/main/scala/termware/CallCCThrowable.scala b/src/main/scala/termware/CallCCThrowable.scala deleted file mode 100644 index af2344f..0000000 --- a/src/main/scala/termware/CallCCThrowable.scala +++ /dev/null @@ -1,12 +0,0 @@ -package termware; - -import scala.util.control.ControlThrowable; - -class CallCCThrowable[A](val trampolineId:TrampolineId, - val current:ComputationBounds[A]) - extends ControlThrowable -{ - def tid = trampolineId -} - - diff --git a/src/main/scala/termware/CaseClassTerm.scala b/src/main/scala/termware/CaseClassTerm.scala deleted file mode 100644 index a12b1c6..0000000 --- a/src/main/scala/termware/CaseClassTerm.scala +++ /dev/null @@ -1,43 +0,0 @@ -package termware - -import scala.reflect._ -import scala.reflect.runtime.universe._ - -class CaseClassToTerm[X <: AnyRef with Product](implicit xtag:TypeTag[X]) extends ComplexToTerm[X] -{ - - lazy val fixedName = SymbolName(Symbol(xtag.tpe.typeSymbol.asClass.name.toString())) - - def name(x:X) = fixedName - - // Members declared in termware.ComplexToTerm - def arity(x: X): Int = x.productArity - - def nameSubterms(x: X): Map[Name, Term] = - fixedNameSubterms - - def fixedNameSubterms: Map[Name, Term] = ??? - - def subterms(x: X): IndexedSeq[Term] = - Reflect.caseClassSubterms(x,xtag) - - def isComplex(x:X): Boolean = x.productArity > 0 - - def isNumber(x: X): Boolean = false - - def numberValue(x: X): Option[scala.math.ScalaNumericAnyConversions] = None - - def xsubstg(x: X,s: termware.Substitution): termware.Term = ??? - - def xsubstv(x: X,s: termware.Substitution): termware.Term = { - new AsTerm(x,this) - } - - def xunify(x: X,y: termware.Term,s: termware.Substitution): termware.UnificationResult = ??? - - -} - - - - diff --git a/src/main/scala/termware/CharTermOps.scala b/src/main/scala/termware/CharTermOps.scala new file mode 100644 index 0000000..f175d7b --- /dev/null +++ b/src/main/scala/termware/CharTermOps.scala @@ -0,0 +1,7 @@ +package termware + +trait CharTermOps { + + this: Term => + +} diff --git a/src/main/scala/termware/ComplexTerm.scala b/src/main/scala/termware/ComplexTerm.scala deleted file mode 100644 index 5f1d826..0000000 --- a/src/main/scala/termware/ComplexTerm.scala +++ /dev/null @@ -1,65 +0,0 @@ -package termware - -import scala.reflect.runtime.universe._ -import scala.math._ - -trait ComplexTerm extends Term -{ - - def isAtom:Boolean = false - - def isPrimitive:Boolean = false - - def isNumber: Boolean = false - - def isComplex: Boolean = true - - // withoyut default mapping to laguage objects. - def is[T](implicit ttag:TypeTag[T]):Boolean = false - - def value[T](implicit ttag:TypeTag[T]):Option[T] = None - - def numberValue: Option[ScalaNumericAnyConversions] = None - - def isX : Boolean = false - - - -} - - -abstract class ComplexToTerm[X](implicit xtag: TypeTag[X]) extends ToTerm[X] -{ - - def name(x:X):Name - - def arity(x:X):Int - - def subterms(x:X):IndexedSeq[Term] - - def nameSubterms(x:X):Map[Name,Term] - - def isAtom(x:X) = false - - def isPrimitive(x:X) = false - - def is[T](x:X)(implicit ttag:TypeTag[T]):Boolean = - (typeOf[T] <:< typeOf[X]) - - def value[T](t:X)(implicit ttag:TypeTag[T]):Option[T] = - if (typeOf[T] <:< typeOf[X]) { - Some(t.asInstanceOf[T]) - } else { - None - } - - type VType = X - - def vTag: TypeTag[X] = xtag - - def v(x:X):X = x - - -} - -// vim: set ts=4 sw=4 et: diff --git a/src/main/scala/termware/ComputationBounds.scala b/src/main/scala/termware/ComputationBounds.scala deleted file mode 100644 index 7cd44cf..0000000 --- a/src/main/scala/termware/ComputationBounds.scala +++ /dev/null @@ -1,258 +0,0 @@ -package termware; - -import scala.reflect.runtime.universe._ -import scala.concurrent._ - - -/** - * result of 'computation chunk' in trampoline. - **/ -sealed abstract class ComputationBounds[+A] -{ - - thisComputationBounds => - - import ComputationBounds._ - - /** - * true when we have result. - */ - def isDone: Boolean; - - /** - * resutl of computations. - */ - def result: Option[A] - - // receive next computation bounds if we not done. - def step(tid:TrampolineId, depth:Int): ComputationBounds[A] - - - def toFuture(implicit executor:ExecutionContext): Future[A] = - Future{ trampoline(this); } - - // Monadic syntax - - - def get: A = trampoline(this); - - def map[B](f: A => B): ComputationBounds[B] = flatMap((x:A) => Done(f(x))) - - - def flatMap[B](f: A => ComputationBounds[B]) = - compose(this, (a:A)=>f(a)) - - /** - * monadic interface where client can see trampolineId and depth. - **/ - class InProcess { - - def map[B](f: A => (TrampolineId,Int) => B): ComputationBounds[B] = - flatMap(x => (tid,depth) => Done(f(x)(tid,depth))) - - def flatMap[B](f: A => (TrampolineId,Int) => ComputationBounds[B]) = - compose(thisComputationBounds, (tid,depth,a:A)=>f(a)(tid,depth)) - - - } - - def inProcess = new InProcess - -} - - - -/** - * when we have some result. - **/ -case class Done[A](val r: A) extends ComputationBounds[A] -{ - def isDone: Boolean = true; - def result: Option[A] = Some(r); - def step(tid:TrampolineId, depth:Int) = this; -} - -/** - * when we need to call net thunk - **/ -case class Call[A]( - thunk: (TrampolineId, Int) => ComputationBounds[A] - ) extends ComputationBounds[A] -{ - def isDone: Boolean = false - def result: Option[A] = None - def step(tId:TrampolineId,depth:Int) = - thunk(tId,depth) -} - -object Call -{ - - def nested[A](tid:TrampolineId, nesting:Int)(block : ((TrampolineId,Int) => ComputationBounds[A])) = - if (nesting > ComputationBounds.MAX_NESTING) { - throw new CallCCThrowable(tid,Call{block}) - } else { - block(tid,nesting+1); - } - -} - - - -case class Compose[A,B] private[termware](source:ComputationBounds[A], - conts: ComputationBounds.Cont[A,B] - ) extends ComputationBounds[B] -{ - import ComputationBounds._ - - def isDone: Boolean = false; - - def result: Option[B] = None; - - def step(tid:TrampolineId, depth:Int) = { - source match { - case Done(a) => - conts match { - case ContOne(f,n) => - try { - f(tid,depth,a) - } catch { - case ex:CallCCThrowable[B] if ex.tid == tid => - ex.current - } - case ContCons(f,g) => - f match { - case ContOne(ff,fdepth) => - var s = try { - ff(tid,depth,a) - } catch { - case ex:CallCCThrowable[_] if ex.tid == tid => - ex.current - } - s match { - case Done(_) => Compose(s,g) - case Call(_) => Compose(s,g) - case Compose(s,f1) => Compose(s,append(f1,g)) - } - case ContCons(f1,f2) => - Compose(source,ContCons(f1,ContCons(f2,g))) - } - } - case Call(_) => - val r = source.step(tid,depth); - r match { - case Done(x) => Compose(r,conts) - case Call(_) => Compose(r,conts) - case Compose(s,f1) => Compose(s,append(f1,conts)) - } - case Compose(s,f1) => Compose(s,append(f1,conts)) - } - } - -} - - -object ComputationBounds -{ - - - def trampoline[A](cb:ComputationBounds[A]):A = { - val trampolineId = TrampolineId.next - var current = cb; - while (!current.isDone) { - current = try { - current.step(trampolineId, 0) - } catch { - case ex : CallCCThrowable[_] if (ex.trampolineId == trampolineId) - => ex.current.asInstanceOf[ComputationBounds[A]] - } - } - current.result.get - } - - def doStep[A](cb:ComputationBounds[A])(trampolineId: TrampolineId, depth:Int):ComputationBounds[A] = - { - if (cb.isDone) { - cb - } else { - try { - cb.step(trampolineId, depth) - } catch { - case ex : CallCCThrowable[_] if (ex.trampolineId == trampolineId) - => ex.current.asInstanceOf[ComputationBounds[A]] - } - } - } - - sealed trait Cont[A,+B] - { - //type From = A; - //type To = B; - } - - case class ContOne[A,B](f: (TrampolineId,Int,A)=> ComputationBounds[B], n: Int = 0) extends Cont[A,B] - - case class ContCons[A,B,C](val x:Cont[A,B], - val y:Cont[B,C]) extends Cont[A,C] - - type ~>[A,B] = Cont[A,B] - - def append[A,B,C](f: A ~> B, g: B ~> C): A ~> C = - { - //System.err.println("append ("+f+","+g+")"); - f match { - case ContOne(ff,nf) => - g match { - case ContOne(fg,ng) if (nf + ng + 1 < MAX_NESTING) => - ContOne({ (tid,depth,a) => - if (depth >= MAX_NESTING - 1) { - Compose(Done(a),ContCons(f,g)) - } else { - val af = try { - ff(tid,depth+1,a) - } catch { - case ex: CallCCThrowable[B] if (ex.tid==tid) => - ex.current - } - if (af.isDone) - fg(tid,depth+1,af.result.get) - else - Compose(af,g) - } - }, - nf + ng + 1) - case ContCons(g1,g2) => - g1 match { - case ContOne(fg1,ng1) if (nf+ng1+1 < MAX_NESTING) => - ContCons(append(f,g1),g2) - case _ => ContCons(f,g) - } - case _ => ContCons(f,g) - } - case ContCons(f1,f2) => ContCons(f1,append(f2,g)) - } - } - - - @inline - def compose[A,B](ca:ComputationBounds[A], - cont:(TrampolineId,Int,A)=>ComputationBounds[B]): ComputationBounds[B] = - ca match { - case Compose(x,xcont) => Compose(x,append(xcont,ContOne(cont))) - case _ => Compose(ca,ContOne(cont)) - } - - - @inline - def compose[A,B](ca:ComputationBounds[A], cont:A=>ComputationBounds[B]): ComputationBounds[B] = - compose(ca,{ (tid:TrampolineId, nesting:Int, x:A) => cont(x)}); - - - - - final val MAX_NESTING=500; - - -} - - diff --git a/src/main/scala/termware/DoubleTermOps.scala b/src/main/scala/termware/DoubleTermOps.scala new file mode 100644 index 0000000..e0718c5 --- /dev/null +++ b/src/main/scala/termware/DoubleTermOps.scala @@ -0,0 +1,7 @@ +package termware + +trait DoubleTermOps extends NumericTermOps { + + this: Term => + +} diff --git a/src/main/scala/termware/FreeComplexTerm.scala b/src/main/scala/termware/FreeComplexTerm.scala deleted file mode 100644 index 2989066..0000000 --- a/src/main/scala/termware/FreeComplexTerm.scala +++ /dev/null @@ -1,57 +0,0 @@ -package termware - -import scala.math._ -import scala.reflect.runtime.universe._ - -case class FreeComplexTerm(val name: Name, - val subterms: IndexedSeq[Term] - )extends ComplexTerm { - - - def arity: Int = subterms.length - - - /** - * unify self with term y - */ - // TODO: add nesting parameter and swith to computatio bounds if one is big. - def unify(y:Term, s0: Substitution): UnificationResult = - if (y.arity != arity) - UnificationFailure(this,y,s0) - else { - var quit = false - var n = arity - var i =0 - var s = s0 - var r: UnificationResult = UnificationSuccess(s) - while( i < arity && !quit) { - val cx = subterm(i).get - val cy = y.subterm(i).get - i += 1 - r = cx.unify(cy,s0) - r match { - case UnificationSuccess(substitution) => - s = substitution - case UnificationFailure(x,y,substitution) => - quit = true - } - } - r - } - - - - /** - * generic substitution, where in right part can be any term - */ - def substg(s:Substitution): Term = - FreeComplexTerm(name,subterms map (_.substg(s))) - - /** - * substitution where in right part can be only variable definitions. - */ - def substv(s: Substitution): Term = - FreeComplexTerm(name, subterms map (_.substv(s))) - - -} \ No newline at end of file diff --git a/src/main/scala/termware/FreeTermSystem.scala b/src/main/scala/termware/FreeTermSystem.scala new file mode 100644 index 0000000..42af48a --- /dev/null +++ b/src/main/scala/termware/FreeTermSystem.scala @@ -0,0 +1,13 @@ +package termware + + +object FreeTermSystem extends TermSystem +{ + + def adopt(t: Term): Term = t + + def mergeAttributes(attrName: Name, x:Term, y:Term): Term = ??? + + +} + diff --git a/src/main/scala/termware/FreeVarTermOps.scala b/src/main/scala/termware/FreeVarTermOps.scala new file mode 100644 index 0000000..0c3edd8 --- /dev/null +++ b/src/main/scala/termware/FreeVarTermOps.scala @@ -0,0 +1,10 @@ +package termware + +trait FreeVarTermOps extends TermEmptyComponents with UnattributedTermOps +{ + + this: FreeVarTerm => + + def isFreeVar: Boolean = true + +} diff --git a/src/main/scala/termware/Int32TermOps.scala b/src/main/scala/termware/Int32TermOps.scala new file mode 100644 index 0000000..3adc733 --- /dev/null +++ b/src/main/scala/termware/Int32TermOps.scala @@ -0,0 +1,7 @@ +package termware + +trait Int32TermOps extends NumericTermOps { + + this: Term => + +} diff --git a/src/main/scala/termware/Int64TermOps.scala b/src/main/scala/termware/Int64TermOps.scala new file mode 100644 index 0000000..8585c94 --- /dev/null +++ b/src/main/scala/termware/Int64TermOps.scala @@ -0,0 +1,7 @@ +package termware + +trait Int64TermOps extends NumericTermOps { + + this: Term => + +} diff --git a/src/main/scala/termware/Name.scala b/src/main/scala/termware/Name.scala index d38b2f9..3cfa387 100644 --- a/src/main/scala/termware/Name.scala +++ b/src/main/scala/termware/Name.scala @@ -1,62 +1,110 @@ package termware -import scala.reflect.runtime.universe.TypeTag -import scala.reflect.runtime.universe.Type -import scala.reflect.runtime.universe.typeOf - sealed trait Name extends Ordered[Name] +{ + def typeIndex: Int + def compare(that: Name): Int = + { + val cmp = typeIndex - that.typeIndex + if (cmp !=0) cmp else compareSameTypeIndex(that) + } -case class SymbolName(s:Symbol) extends Name -{ - - def compare(x:Name):Int = - x match { - case SymbolName(sx) => if (s eq sx) 0 - else { - var c = s.hashCode - sx.hashCode - if (c!=0) { - c - } else { - s.toString.compare(sx.toString) - } - } - case PrimitiveName(v) => -1 - } + def compareSameTypeIndex(that: Name): Int } -case class PrimitiveName[V:TypeTag](v:V)(implicit ord:Ordering[V]) extends Name -{ - - def valueType: Type = typeOf[V] - - def compare(x:Name):Int = - x match { - case SymbolName(_) => 1 - case xp@PrimitiveName(xv) => - var c = valueType.hashCode - xp.valueType.hashCode - if (c != 0) - c - else if (xp.valueType <:< valueType) - ord.compare(v, xv.asInstanceOf[V]) - else { - // hashCodes are equals but types are differeent - // very rare. - c = valueType.toString.compare(xp.valueType.toString) - if ( c == 0) { - // very-very-very rare. near newer - c = v.hashCode - xp.v.hashCode - if (c == 0) { - c = v.toString.compare(xp.v.toString) - } - } - c - } - - } +sealed abstract class StringLikeName(val value:String) extends Name +{ + + def compareSameTypeIndex(that: Name) = + value compare that.asInstanceOf[StringLikeName].value } +object NameTypeIndexes +{ + val ATOM = 1 + val STRING = 2 + val LONG = 3 + val INT = 4 + val CHAR = 5 + val DOUBLE = 6 + val OPAQUE = 7 +} + +import NameTypeIndexes._ + +case class AtomName(v:String) extends StringLikeName(v) +{ + def typeIndex = ATOM +} + +case class StringName(v:String) extends StringLikeName(v) +{ + def typeIndex = STRING +} + +sealed class CharLikeName(val value:Char) extends Name +{ + def typeIndex = CHAR + + def compareSameTypeIndex(that: Name) = + value compare that.asInstanceOf[CharLikeName].value +} + +case class CharName(v: Char) extends CharLikeName(v) + +case class LongName(val value:Long) extends Name +{ + + def typeIndex = LONG + + def compareSameTypeIndex(that: Name) = + value compare that.asInstanceOf[LongName].value + +} + +case class IntName(val value:Int) extends Name +{ + + def typeIndex = INT + + def compareSameTypeIndex(that: Name) = + value compare that.asInstanceOf[IntName].value + +} + +case class DoubleName(val value: Double) extends Name +{ + + def typeIndex = DOUBLE + + def compareSameTypeIndex(that: Name) = + value compare that.asInstanceOf[DoubleName].value + +} + +case class OpaqueName(val value: Array[Byte]) extends Name +{ + + def typeIndex = OPAQUE + + def compareSameTypeIndex(that: Name) = + { + val other = that.asInstanceOf[OpaqueName] + var c = value.length - other.value.length + if (c!=0) { + c + } else { + var i=0; + while(c!=0 && i + +} diff --git a/src/main/scala/termware/OpaqueTermOps.scala b/src/main/scala/termware/OpaqueTermOps.scala new file mode 100644 index 0000000..c316c0e --- /dev/null +++ b/src/main/scala/termware/OpaqueTermOps.scala @@ -0,0 +1,9 @@ +package termware + + +trait OpaqueTermOps extends PrimitiveTermOps +{ + + this: OpaqueTerm => + +} diff --git a/src/main/scala/termware/PrimitiveTerm.scala b/src/main/scala/termware/PrimitiveTerm.scala deleted file mode 100644 index 1b11068..0000000 --- a/src/main/scala/termware/PrimitiveTerm.scala +++ /dev/null @@ -1,90 +0,0 @@ -package termware - -import scala.reflect.runtime.universe._ -import scala.math._ -import scala.util.{Try => UTry} - - -abstract class PrimitiveToTerm[X](implicit xtag: TypeTag[X], ord:Ordering[X]) extends ToTerm[X] -{ - - def name(x:X):Name = PrimitiveName[X](x) - - def arity(x:X) = 0 - - def subterms(x:X):IndexedSeq[BaseAsTerm] = IndexedSeq() - - def nameSubterms(x:X):Map[Name,BaseAsTerm] = Map() - - @inline def isAtom(x:X) = false - - @inline def isPrimitive(x:X) = true - - @inline def isComplex(x:X) = false - - def is[T](x:X)(implicit ttag:TypeTag[T]):Boolean = - (typeOf[T] <:< typeOf[X]) - - def value[T](t:X)(implicit ttag:TypeTag[T]):Option[T] = - if (typeOf[T] <:< typeOf[X]) { - Some(t.asInstanceOf[T]) - } else { - None - } - - type VType = X - - def vTag: TypeTag[X] = xtag - - def v(x:X):X = x - - def xunify(x: X, y: Term, s: Substitution): UnificationResult = ??? - - def xsubstg(x: X, s: Substitution): Term = - { - val t = AsTerm[X](x,this) - s.getOrElse(t,t) - } - - def xsubstv(x: X, s: Substitution): Term - = AsTerm[X](x, this) - -} - -class NumericToTerm[X <% ScalaNumericAnyConversions](implicit xtag:TypeTag[X], ord:Ordering[X]) extends PrimitiveToTerm[X] -{ - - override def isNumber(x:X) = true - - override def numberValue(x:X) = Some(x) - -} - -object IntToTerm extends NumericToTerm[Int] - -object LongToTerm extends NumericToTerm[Long] - -object FloatToTerm extends NumericToTerm[Float] - -object DoubleToTerm extends NumericToTerm[Double] - -// bag in compiler ??? -// (now implicit val is instantiated in package object) -//object BigDecimalToTerm extends NumericToTerm[BigDecimal] -// -//object BigIntToTerm extends NumericToTerm[BigInt](typeTag[BigInt]) - -class NonNumericPrimitiveToTerm[X:TypeTag](implicit ord:Ordering[X]) extends PrimitiveToTerm[X] -{ - - def isNumber(x:X) = false - - def numberValue(x:X) = None - -} - -// -//object StringToTerm extends NonNumericPrimitiveToTerm[String] - - -// vim: set ts=4 sw=4 et: diff --git a/src/main/scala/termware/PrimitiveTermOps.scala b/src/main/scala/termware/PrimitiveTermOps.scala new file mode 100644 index 0000000..2248f86 --- /dev/null +++ b/src/main/scala/termware/PrimitiveTermOps.scala @@ -0,0 +1,18 @@ +package termware + + +trait PrimitiveTermOps extends UnattributedTermOps +{ + this: PrimitiveTerm => + + def arity = 0 + + def component(n:Name) = None + + def component(i:Int) = None + + def componentNames : IndexedSeq[Name] = IndexedSeq() + + def isFreeVar = false + +} diff --git a/src/main/scala/termware/Reflect.scala b/src/main/scala/termware/Reflect.scala deleted file mode 100644 index 359b751..0000000 --- a/src/main/scala/termware/Reflect.scala +++ /dev/null @@ -1,58 +0,0 @@ -package termware - -import scala.reflect.runtime.universe._ - -/** - * reconstruct mapping from scala object to terms, as in default system - */ -object Reflect { - - def caseClassSubterms[X <: AnyRef with Product](x:X, xtag: TypeTag[X]): IndexedSeq[Term] = - { - ??? - } - - @specialized - def asTerm[X](x:X, xtag: TypeTag[X]): Term = - { - val ts = xtag.tpe.typeSymbol - if (ts.isClass) { - val cs = ts.asClass - if (cs.isPrimitive) { - if (cs.isNumeric) { - if (xtag.tpe =:= typeOf[Long]) { - AsTerm.create[Long](x.asInstanceOf[Long]) - } else if (xtag.tpe =:= typeOf[Int]) { - AsTerm.create[Int](x.asInstanceOf[Int]) - } else if (xtag.tpe =:= typeOf[Float]) { - AsTerm.create[Float](x.asInstanceOf[Float]) - } else { - ??? - } - } else if (xtag.tpe =:= typeOf[Char]) { - AsTerm.create[Char](x.asInstanceOf[Char]) - } else if (xtag.tpe =:= typeOf[Boolean]) { - AsTerm.create[Boolean](x.asInstanceOf[Boolean]) - } else if (xtag.tpe =:= typeOf[Unit]) { - /// AsTerm.create[Unit](()) - ??? - } else { - throw new IllegalArgumentException("Unknown primitive:"+cs) - } - } else if (cs.isCaseClass) { - val xxtag = xtag.asInstanceOf[TypeTag[({ type Y <: AnyRef with Product })#Y ]] - val cct = new CaseClassToTerm[({ type Y <: AnyRef with Product })#Y]()(xxtag) - new AsTerm(x.asInstanceOf[({ type Y <: AnyRef with Product })#Y], cct)(xxtag) - } else if (xtag.tpe =:= typeOf[String]) { - AsTerm.create[String](x.asInstanceOf[String]) - } else { - ??? - // TODO: AnyRef term. - } - } else { - ??? - } - } - - -} diff --git a/src/main/scala/termware/StringTermOps.scala b/src/main/scala/termware/StringTermOps.scala new file mode 100644 index 0000000..f591176 --- /dev/null +++ b/src/main/scala/termware/StringTermOps.scala @@ -0,0 +1,9 @@ +package termware + + +trait StringTermOps extends PrimitiveTermOps +{ + + this: StringTerm => + +} diff --git a/src/main/scala/termware/StructuredTermOps.scala b/src/main/scala/termware/StructuredTermOps.scala new file mode 100644 index 0000000..cb3d132 --- /dev/null +++ b/src/main/scala/termware/StructuredTermOps.scala @@ -0,0 +1,23 @@ +package termware + + +trait StructuredTermOps extends UnattributedTermOps +{ + + this: StructuredTerm => + + def arity = components.length + + def name = termStructure.name + + def componentNames = termStructure.componentNames + + def component(i:Int) = if (i < components.length) { + Some(components(i)) + } else None + + def component(n:Name) = termStructure.componentIndexes.get(n) map(components(_)) + + def isFreeVar: Boolean = false + +} diff --git a/src/main/scala/termware/Substitution.scala b/src/main/scala/termware/Substitution.scala deleted file mode 100644 index cbb23a4..0000000 --- a/src/main/scala/termware/Substitution.scala +++ /dev/null @@ -1,87 +0,0 @@ -package termware; - -import scala.collection.immutable.TreeMap -import scala.util._ -import scala.reflect.runtime.universe._ - - -trait Substitution extends PartialFunction[Term,Term] -{ - - def isEmpty: Boolean - - def get(k:Term): Option[Term] - - def getOrElse(k:Term, default: Term): Term = - get(k) match { - case Some(x) => x - case None => default - } - - def put(k:Term, v:Term): UnificationResult - - def merge(s: Substitution): UnificationResult - - def withIndex(newZipIndex:BigInt): Substitution - - def lastZipIndex: BigInt - - def foreach(f:((Term,Term)) => Unit): Unit - - def find(f:((Term,Term))=>Boolean): Option[(Term,Term)] - -} - - -object STMSubstitution -{ - def empty = new STMSubstitution(TreeMap[Term,Tuple2[BigInt,Term]](),BigInt(1)); -} - - -case class STMSubstitution(val map: Map[Term,Tuple2[BigInt,Term]], - val lastZipIndex: BigInt) - extends Substitution -{ - - def withIndex(newZipIndex:BigInt):STMSubstitution = { - val cmp = lastZipIndex.compare(newZipIndex); - if (cmp > 0) - new STMSubstitution(map,newZipIndex) - else if (cmp < 0) - new STMSubstitution( - map.filter({ _._2._1 < newZipIndex }),newZipIndex) - else /* newZipIndex == lastZipIndex */ - this; - } - - def get(k:Term) = map.get(k) map (_._2) - - def put(k:Term, v:Term): UnificationResult = { - map.get(k) match { - case None => UnificationSuccess(STMSubstitution(map.updated(k,(lastZipIndex,v)),lastZipIndex)) - case Some((v1,i1)) => - v.unify(v1, this) flatMap (merge(_)) - } - } - - - def merge(s:Substitution): UnificationResult = { - ??? - } - - override def find(f:((Term,Term))=>Boolean): Option[(Term,Term)] = - map.mapValues(_._2).find(f) - - override def isEmpty = map.isEmpty - - override def isDefinedAt(t:Term) = map.isDefinedAt(t) - - override def apply(t:Term):Term = map(t)._2 - - override def foreach(f:((Term,Term))=>Unit) = map.mapValues(_._2).foreach(f) - - -} - - diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index ccaa0b5..c7001a8 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -1,167 +1,82 @@ package termware -import scala.math._ -import scala.util._ -import scala.reflect.runtime.universe._ -trait Term -{ - - def name: Name - - def arity: Int - - def subterms:IndexedSeq[Term] - - def subterm(i:Int): Option[Term] = - if (i y - */ - def unify(y:Term, s: Substitution): UnificationResult +sealed trait Term extends TermOps - /** - * generic substitution, where in right part can be any term - */ - def substg(s:Substitution): Term - - /** - * substitution where in right part can be only variable definitions. - */ - def substv(s:Substitution): Term +sealed trait UnattributedTerm extends Term +class AtomTerm(value:String) extends UnattributedTerm with AtomTermOps +{ + val name = AtomName(value) } - -/** - * typeclass for term algebra. - */ -abstract class ToTerm[X:TypeTag] +sealed trait AttributedTerm extends Term { + def unattributed: Term + def attributes: Map[Name,Term] +} - type Origin = X - - def name(x:X):Name - - def arity(x:X):Int - - def subterms(x:X):IndexedSeq[Term] - - def subterm(x:X,i:Int): Option[Term] = - if (i + + val attributes: Map[Name,Term] = Map() + + +} diff --git a/src/main/scala/termware/TermEmptyComponents.scala b/src/main/scala/termware/TermEmptyComponents.scala new file mode 100644 index 0000000..4108c36 --- /dev/null +++ b/src/main/scala/termware/TermEmptyComponents.scala @@ -0,0 +1,18 @@ +package termware + + +trait TermEmptyComponents +{ + + this: Term => + + def arity = 0 + + def component(n:Name) = None + + def component(i:Int) = None + + def componentNames:IndexedSeq[Name] = IndexedSeq() + +} + diff --git a/src/main/scala/termware/TermOps.scala b/src/main/scala/termware/TermOps.scala new file mode 100644 index 0000000..1029f28 --- /dev/null +++ b/src/main/scala/termware/TermOps.scala @@ -0,0 +1,25 @@ +package termware + +trait TermOps +{ + this: Term => + + def name: Name + + def arity: Int + + def componentNames: IndexedSeq[Name] + + def component(i: Int): Option[Term] + + def component(n: Name): Option[Term] + + def isAttributed: Boolean + + def isSystemized: Boolean + + def attributes: Map[Name,Term] + + def isFreeVar: Boolean + +} diff --git a/src/main/scala/termware/TermOrdering.scala b/src/main/scala/termware/TermOrdering.scala deleted file mode 100644 index 03b8d19..0000000 --- a/src/main/scala/termware/TermOrdering.scala +++ /dev/null @@ -1,35 +0,0 @@ -package termware - -object TermOrdering extends Ordering[Term] -{ - - //TODO: optimize, check one level before call trampoline. - def compare(x:Term, y:Term):Int = - cbCompare(x,y).get - - def cbCompare(x:Term, y:Term):ComputationBounds[Int] = - { - (x.arity - y.arity) match { - case c if c!=0 => Done(c) - case _ => - (x.name compare y.name) match { - case c if c!=0 => Done(c) - case _ => cbCompare(x.subterms, y.subterms) - } - } - } - - def cbCompare(x:IndexedSeq[Term], y:IndexedSeq[Term]):ComputationBounds[Int]= - { - if (x.isEmpty) - Done(if (y.isEmpty) 0 else -1) - else if (y.isEmpty) - Done(1) - else - cbCompare(x.head, y.head) flatMap { r => - if (r!=0) Done(r) else cbCompare(x.tail, y.tail) - } - } - -} - diff --git a/src/main/scala/termware/TermStructure.scala b/src/main/scala/termware/TermStructure.scala new file mode 100644 index 0000000..4e8dca2 --- /dev/null +++ b/src/main/scala/termware/TermStructure.scala @@ -0,0 +1,17 @@ +package termware + +trait TermStructure +{ + def name: Name + + def componentIndexes: Map[Name,Int] + + def componentNames: IndexedSeq[Name] +} + +case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) extends TermStructure +{ + + val componentIndexes = componentNames.foldLeft(Map[Name,Int]()){ (s,e) => s.updated(e,s.size+1) } + +} diff --git a/src/main/scala/termware/TermSystem.scala b/src/main/scala/termware/TermSystem.scala index fbac4b1..657ed49 100644 --- a/src/main/scala/termware/TermSystem.scala +++ b/src/main/scala/termware/TermSystem.scala @@ -1,14 +1,12 @@ package termware -import scala.reflect.runtime.universe._ - - trait TermSystem { - def toTerm[T](t:T)(implicit ttag: TypeTag[T]): Either[String,Term] + def adopt(t: Term): Term - def fromTerm[T](t: Term)(implicit ttag: TypeTag[T]): Either[String,T] + def mergeAttributes(attrName: Name, x:Term, y:Term): Term } + diff --git a/src/main/scala/termware/TrampolineId.scala b/src/main/scala/termware/TrampolineId.scala deleted file mode 100644 index 8fa0c54..0000000 --- a/src/main/scala/termware/TrampolineId.scala +++ /dev/null @@ -1,20 +0,0 @@ -package termware; - -import scala.util._ - -class TrampolineId(val x:Long) extends AnyVal - -object TrampolineId -{ - def next: TrampolineId = - { - val threadId = Thread.currentThread.getId - val localId = local.value + 1 - local.value = localId - new TrampolineId((threadId << 16) + localId) - } - - private[this] val local = new DynamicVariable[Int](0) - -} - diff --git a/src/main/scala/termware/UnattributedTermOps.scala b/src/main/scala/termware/UnattributedTermOps.scala new file mode 100644 index 0000000..a7a09f2 --- /dev/null +++ b/src/main/scala/termware/UnattributedTermOps.scala @@ -0,0 +1,14 @@ +package termware + +trait UnattributedTermOps +{ + this: UnattributedTerm => + + def isAttributed: Boolean = false + + def attributes: Map[Name,Term] = Map() + + def isSystemized: Boolean = false + + def termSystem: TermSystem = FreeTermSystem +} diff --git a/src/main/scala/termware/UnificationResult.scala b/src/main/scala/termware/UnificationResult.scala deleted file mode 100644 index f175330..0000000 --- a/src/main/scala/termware/UnificationResult.scala +++ /dev/null @@ -1,37 +0,0 @@ -package termware - - -sealed trait UnificationResult -{ - def isSuccess: Boolean - def isFailure: Boolean - - def toOption: Option[Substitution] - - def map(f: Substitution => Substitution): UnificationResult - - def flatMap(f: Substitution => UnificationResult): UnificationResult - -} - -case class UnificationSuccess(s:Substitution) extends UnificationResult -{ - @inline def isSuccess = true - @inline def isFailure = false - @inline def substitution = s - @inline def toOption: Option[Substitution] = Some(s) - @inline def map(f: Substitution => Substitution) = UnificationSuccess(f(s)) - @inline def flatMap(f: Substitution => UnificationResult): UnificationResult = f(s) - -} - -case class UnificationFailure(x:Term,y:Term,s:Substitution) extends UnificationResult -{ - @inline def isSuccess = false - @inline def isFailure = true - @inline def toOption: Option[Substitution] = None - @inline def map(f: Substitution => Substitution) = this - @inline def flatMap(f: Substitution => UnificationResult): UnificationResult = this -} - - diff --git a/src/main/scala/termware/package.scala b/src/main/scala/termware/package.scala deleted file mode 100644 index 1c58f2b..0000000 --- a/src/main/scala/termware/package.scala +++ /dev/null @@ -1,37 +0,0 @@ -import language.implicitConversions - -import scala.reflect.runtime.universe.TypeTag - - -package object termware { - - - implicit def toTerm[T:TypeTag](x:T)(implicit ops:ToTerm[T]) = new AsTerm(x,ops) - - implicit val intToTerm = IntToTerm - implicit val longToTerm = LongToTerm - implicit val floatToTerm = FloatToTerm - implicit val doubleToTerm = DoubleToTerm - - implicit val bigDecimalToTerm = new NumericToTerm[BigDecimal] - implicit val bigIntToTerm = new NumericToTerm[BigInt] - - implicit val stringToTerm = new NonNumericPrimitiveToTerm[String] - implicit val charToTerm = new NonNumericPrimitiveToTerm[Char] - implicit val booleanToTerm = new NonNumericPrimitiveToTerm[Boolean] - - - implicit val atomTerm = AtomToTerm - - implicit val termOrdering: Ordering[Term] = TermOrdering - - - - @inline - implicit class TermSymbolApply(s: Symbol) - { - def apply(args:Term*): Term = - new FreeComplexTerm(SymbolName(s),args.toIndexedSeq) - } - -} diff --git a/src/test/scala/termware/BaseTermFunSuite.scala b/src/test/scala/termware/BaseTermFunSuite.scala deleted file mode 100644 index 0e738df..0000000 --- a/src/test/scala/termware/BaseTermFunSuite.scala +++ /dev/null @@ -1,47 +0,0 @@ -package termware - - -import org.scalatest.FunSuite -import org.scalatest.matchers.ShouldMatchers - -class BaseTermFunSuite extends FunSuite - with ShouldMatchers -{ - - test("int term must exists") { - val t: Term = 5 - t.arity should be(0) - val subterms = 5.subterms - t.is[Int] should be(true) - t.value[Int] should be(Some(5)) - t.isNumber should be(true) - } - - test("long term must exists") { - val t: Term = 5L - t.arity should be(0) - t.is[Long] should be(true) - t.is[Int] should be(false) - t.value[Long] should be(Some(5L)) - t.isNumber should be(true) - t.numberValue.get.intValue() should be(5) - } - - test("string term") { - val t: Term = "AAA" - t.arity should be(0) - t.is[String] should be(true) - t.value[String] should be(Some("AAA")) - } - - test("atom term") { - val t:Term = 'a - t.arity should be(0) - t.isAtom should be(true) - } - - -} - - -// vim: set ts=4 sw=4 et: diff --git a/src/test/scala/termware/ComputationBoundsFunSuite.scala b/src/test/scala/termware/ComputationBoundsFunSuite.scala deleted file mode 100644 index 034993d..0000000 --- a/src/test/scala/termware/ComputationBoundsFunSuite.scala +++ /dev/null @@ -1,73 +0,0 @@ -package termware - - -import org.scalatest.FunSuite -import org.scalatest.matchers.ShouldMatchers - -class ComputationBoundsFunSuite extends FunSuite - with ShouldMatchers -{ - - test("100000 recursive calls must be handled") { - def f1(n:Int): ComputationBounds[Int] = Call{ (tid,depth) => - //System.err.println("f1(%d), nesting=%s".format(n,depth.toString)); - if (n==0) Done(0) - else if (n>0) { - Call.nested(tid,depth){ (tid, depth) => - //System.err.println("in nested, depth="+depth.toString); - for(x <- f1(n-1)) yield x+n ; - } - } else { - throw new IllegalArgumentException("n must be >0"); - } - } - def f2(n:Int):Int = (1 to n).sum - try { - val x1 = f1(100000).get - val x2 = f2(100000) - x1 should equal(x2) - } catch { - case ex: StackOverflowError => ex.printStackTrace(); - throw new RuntimeException(ex); - } - } - - test("internal rec call must be work") { - def f1(n:Int): ComputationBounds[Int] = Call{ (tid,depth) => - //System.err.println("f1(%d), depth=%d".format(n,depth)); - if (n==0) Done(0) - else if (n>0) { - for(x <- f1(n-1)) yield x+n ; - } else { - throw new IllegalArgumentException("n must be >0"); - } - } - def f2(n:Int):Int = (1 to n).sum - val x1 = f1(100000).get - val x2 = f2(100000) - x1 should equal(x2) - } - - test("inProcess shoud show depth and trampolineId") { - var maxDepth: Int = 0; - def f(n:Int):ComputationBounds[Int] = Call{ (tid, depth) => - //System.err.println("f1(%d), depth=%d".format(n,depth)); - if (n > 1) { - for(x <- f(n-1).inProcess) yield { - (tid,depth) => //System.err.println("tid="+tid+", depth="+depth) - if (n > maxDepth) { - maxDepth = n - } - n + depth - } - } else Done(1) - } - val x = f(10).get - maxDepth should be >(0) - } - - -} - - -// vim: set ts=4 sw=4 et: diff --git a/src/test/scala/termware/FreeCompleTermFunSuite.scala b/src/test/scala/termware/FreeCompleTermFunSuite.scala deleted file mode 100644 index 254c1a9..0000000 --- a/src/test/scala/termware/FreeCompleTermFunSuite.scala +++ /dev/null @@ -1,29 +0,0 @@ -package termware - -import org.scalatest.FunSuite - -class FreeCompleTermFunSuite extends FunSuite - // note, that ShoultMatchers conflicts with free term constructor -{ - - test("free complex term") { - val t: Term = 'f(1,'g(3),3,"AAA") - assert(t.arity==4) - val f0 = t.subterms(0) - assert(f0.is[Int]) - val f1 = t.subterms(1) - assert(f1.isComplex) - assert(f1.arity==1) - /* - t match { - case Term('f,args) => args(0) should be equal(f0) - } - */ - - } - - -} - - -// vim: set ts=4 sw=4 et: From 24e7de8c69c28435345f0b92d9538eb7120521a8 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 21 Nov 2015 20:07:53 +0200 Subject: [PATCH 13/27] all terms are attributed. --- build.sbt | 1 - src/main/scala/termware/AtomTermOps.scala | 8 ++- .../scala/termware/AttributedTermOps.scala | 24 -------- src/main/scala/termware/DoubleTermOps.scala | 2 +- src/main/scala/termware/FreeTermSystem.scala | 5 +- src/main/scala/termware/FreeVarTermOps.scala | 10 ---- src/main/scala/termware/Int32TermOps.scala | 2 +- src/main/scala/termware/Int64TermOps.scala | 2 +- src/main/scala/termware/Name.scala | 2 + src/main/scala/termware/NumericTermOps.scala | 2 +- .../scala/termware/PrimitiveTermOps.scala | 16 ++++-- .../scala/termware/StructuredTermOps.scala | 16 +++--- src/main/scala/termware/Term.scala | 56 +++++++------------ src/main/scala/termware/TermAttributes.scala | 5 +- src/main/scala/termware/TermOps.scala | 8 +-- src/main/scala/termware/TermSystem.scala | 3 + .../scala/termware/UnattributedTermOps.scala | 14 ----- src/main/scala/termware/VarTermOps.scala | 11 ++++ 18 files changed, 72 insertions(+), 115 deletions(-) delete mode 100644 src/main/scala/termware/AttributedTermOps.scala delete mode 100644 src/main/scala/termware/FreeVarTermOps.scala delete mode 100644 src/main/scala/termware/UnattributedTermOps.scala create mode 100644 src/main/scala/termware/VarTermOps.scala diff --git a/build.sbt b/build.sbt index 97efec7..1d37bf2 100644 --- a/build.sbt +++ b/build.sbt @@ -14,7 +14,6 @@ libraryDependencies <+= (scalaVersion){ "org.scala-lang" % "scala-reflect" % _ } libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.1" % "test" - publishMavenStyle := true publishTo <<= version { (v: String) => diff --git a/src/main/scala/termware/AtomTermOps.scala b/src/main/scala/termware/AtomTermOps.scala index 29431d7..149ecde 100644 --- a/src/main/scala/termware/AtomTermOps.scala +++ b/src/main/scala/termware/AtomTermOps.scala @@ -1,12 +1,16 @@ package termware -trait AtomTermOps extends TermEmptyComponents with UnattributedTermOps +trait AtomTermOps extends TermEmptyComponents { this: AtomTerm => - def isFreeVar = false + override def isScoped = true + + override def scope = None + + override def isVar = false } diff --git a/src/main/scala/termware/AttributedTermOps.scala b/src/main/scala/termware/AttributedTermOps.scala deleted file mode 100644 index 3164596..0000000 --- a/src/main/scala/termware/AttributedTermOps.scala +++ /dev/null @@ -1,24 +0,0 @@ -package termware - -trait AttributedTermOps -{ - this: AttributedTerm => - - def name: Name = unattributed.name - - def arity: Int = unattributed.arity - - def componentNames: IndexedSeq[Name] = - unattributed.componentNames - - def component(i: Int): Option[Term] = - unattributed.component(i) - - def component(n: Name): Option[Term] = - unattributed.component(n) - - def isAttributed: Boolean = true - - def isFreeVar: Boolean = unattributed.isFreeVar - -} diff --git a/src/main/scala/termware/DoubleTermOps.scala b/src/main/scala/termware/DoubleTermOps.scala index e0718c5..3403366 100644 --- a/src/main/scala/termware/DoubleTermOps.scala +++ b/src/main/scala/termware/DoubleTermOps.scala @@ -2,6 +2,6 @@ package termware trait DoubleTermOps extends NumericTermOps { - this: Term => + this: DoubleTerm => } diff --git a/src/main/scala/termware/FreeTermSystem.scala b/src/main/scala/termware/FreeTermSystem.scala index 42af48a..af4af60 100644 --- a/src/main/scala/termware/FreeTermSystem.scala +++ b/src/main/scala/termware/FreeTermSystem.scala @@ -4,10 +4,13 @@ package termware object FreeTermSystem extends TermSystem { + def name: Term = new AtomTerm("Free") + def adopt(t: Term): Term = t def mergeAttributes(attrName: Name, x:Term, y:Term): Term = ??? - + + def isFree: Boolean = true } diff --git a/src/main/scala/termware/FreeVarTermOps.scala b/src/main/scala/termware/FreeVarTermOps.scala deleted file mode 100644 index 0c3edd8..0000000 --- a/src/main/scala/termware/FreeVarTermOps.scala +++ /dev/null @@ -1,10 +0,0 @@ -package termware - -trait FreeVarTermOps extends TermEmptyComponents with UnattributedTermOps -{ - - this: FreeVarTerm => - - def isFreeVar: Boolean = true - -} diff --git a/src/main/scala/termware/Int32TermOps.scala b/src/main/scala/termware/Int32TermOps.scala index 3adc733..882e0b5 100644 --- a/src/main/scala/termware/Int32TermOps.scala +++ b/src/main/scala/termware/Int32TermOps.scala @@ -2,6 +2,6 @@ package termware trait Int32TermOps extends NumericTermOps { - this: Term => + this: Int32Term => } diff --git a/src/main/scala/termware/Int64TermOps.scala b/src/main/scala/termware/Int64TermOps.scala index 8585c94..411e900 100644 --- a/src/main/scala/termware/Int64TermOps.scala +++ b/src/main/scala/termware/Int64TermOps.scala @@ -2,6 +2,6 @@ package termware trait Int64TermOps extends NumericTermOps { - this: Term => + this: Int64Term => } diff --git a/src/main/scala/termware/Name.scala b/src/main/scala/termware/Name.scala index 3cfa387..3485081 100644 --- a/src/main/scala/termware/Name.scala +++ b/src/main/scala/termware/Name.scala @@ -3,7 +3,9 @@ package termware sealed trait Name extends Ordered[Name] { + def typeIndex: Int + def compare(that: Name): Int = { val cmp = typeIndex - that.typeIndex diff --git a/src/main/scala/termware/NumericTermOps.scala b/src/main/scala/termware/NumericTermOps.scala index 307ec47..681288d 100644 --- a/src/main/scala/termware/NumericTermOps.scala +++ b/src/main/scala/termware/NumericTermOps.scala @@ -2,6 +2,6 @@ package termware trait NumericTermOps { - this: Term => + this: NumericTerm => } diff --git a/src/main/scala/termware/PrimitiveTermOps.scala b/src/main/scala/termware/PrimitiveTermOps.scala index 2248f86..4d05347 100644 --- a/src/main/scala/termware/PrimitiveTermOps.scala +++ b/src/main/scala/termware/PrimitiveTermOps.scala @@ -1,18 +1,22 @@ package termware -trait PrimitiveTermOps extends UnattributedTermOps +trait PrimitiveTermOps { this: PrimitiveTerm => - def arity = 0 + override def arity = 0 - def component(n:Name) = None + override def component(n:Name) = None - def component(i:Int) = None + override def component(i:Int) = None - def componentNames : IndexedSeq[Name] = IndexedSeq() + override def componentNames : IndexedSeq[Name] = IndexedSeq() - def isFreeVar = false + override def isVar = false + + override def isScoped = false + + override def scope = None } diff --git a/src/main/scala/termware/StructuredTermOps.scala b/src/main/scala/termware/StructuredTermOps.scala index cb3d132..f4cdb6f 100644 --- a/src/main/scala/termware/StructuredTermOps.scala +++ b/src/main/scala/termware/StructuredTermOps.scala @@ -1,23 +1,25 @@ package termware -trait StructuredTermOps extends UnattributedTermOps +trait StructuredTermOps extends TermOps { this: StructuredTerm => - def arity = components.length + override def arity = components.length - def name = termStructure.name + override def name = termStructure.name - def componentNames = termStructure.componentNames + override def componentNames = termStructure.componentNames - def component(i:Int) = if (i < components.length) { + override def component(i:Int) = if (i < components.length) { Some(components(i)) } else None - def component(n:Name) = termStructure.componentIndexes.get(n) map(components(_)) + override def component(n:Name) = termStructure.componentIndexes.get(n) map(components(_)) - def isFreeVar: Boolean = false + override def isVar: Boolean = false + + override def isScoped = scope.isDefined } diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index c7001a8..ed0f3df 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -2,42 +2,19 @@ package termware sealed trait Term extends TermOps - -sealed trait UnattributedTerm extends Term - -class AtomTerm(value:String) extends UnattributedTerm with AtomTermOps -{ - val name = AtomName(value) -} - -sealed trait AttributedTerm extends Term -{ - def unattributed: Term - def attributes: Map[Name,Term] -} - -class SimpleAttributedTerm(t: UnattributedTerm, a: Map[Name, Term]) extends AttributedTerm with AttributedTermOps { - def unattributed = t - def attributes = a - - def isSystemized = false + val attributes: Map[Name,Term] = Map() + val termSystem: TermSystem = FreeTermSystem } -sealed trait SystemizedTerm extends AttributedTerm - -class SystemizedAttributedTerm(t: UnattributedTerm, a: Map[Name, Term], ts: TermSystem) extends AttributedTerm - with AttributedTermOps +class AtomTerm(value:String, + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem) extends Term with AtomTermOps { - def unattributed = t - def attributes = a - - def isSystemized = false - def termSystem = ts + val name = AtomName(value) } - -sealed trait PrimitiveTerm extends UnattributedTerm with PrimitiveTermOps with UnattributedTermOps +sealed trait PrimitiveTerm extends Term with PrimitiveTermOps class StringTerm(value:String) extends PrimitiveTerm with StringTermOps { @@ -71,12 +48,17 @@ case class OpaqueTerm(value: Array[Byte]) extends PrimitiveTerm with OpaqueTermO val name = OpaqueName(value) } - -case class StructuredTerm(termStructure: TermStructure, components: IndexedSeq[Term]) extends UnattributedTerm with StructuredTermOps - -class FreeVarTerm(val name:Name) extends UnattributedTerm with FreeVarTermOps - - -//class LetVarTerm extends Term +case class StructuredTerm(termStructure: TermStructure, + components: IndexedSeq[Term], + override val scope: Option[Term] = None, + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem + ) extends Term with StructuredTermOps + +class VarTerm(val name: Name, + override val scope: Option[Term] = None, + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem + ) extends Term with VarTermOps diff --git a/src/main/scala/termware/TermAttributes.scala b/src/main/scala/termware/TermAttributes.scala index fe2aa93..92540a3 100644 --- a/src/main/scala/termware/TermAttributes.scala +++ b/src/main/scala/termware/TermAttributes.scala @@ -3,9 +3,6 @@ package termware trait TermAttributes { - this: AttributedTerm => - - val attributes: Map[Name,Term] = Map() - + this: Term => } diff --git a/src/main/scala/termware/TermOps.scala b/src/main/scala/termware/TermOps.scala index 1029f28..eaf90f6 100644 --- a/src/main/scala/termware/TermOps.scala +++ b/src/main/scala/termware/TermOps.scala @@ -14,12 +14,10 @@ trait TermOps def component(n: Name): Option[Term] - def isAttributed: Boolean + def isScoped: Boolean - def isSystemized: Boolean + def scope: Option[Term] - def attributes: Map[Name,Term] - - def isFreeVar: Boolean + def isVar: Boolean } diff --git a/src/main/scala/termware/TermSystem.scala b/src/main/scala/termware/TermSystem.scala index 657ed49..7d16d41 100644 --- a/src/main/scala/termware/TermSystem.scala +++ b/src/main/scala/termware/TermSystem.scala @@ -4,9 +4,12 @@ package termware trait TermSystem { + def name: Term + def adopt(t: Term): Term def mergeAttributes(attrName: Name, x:Term, y:Term): Term + def isFree: Boolean } diff --git a/src/main/scala/termware/UnattributedTermOps.scala b/src/main/scala/termware/UnattributedTermOps.scala deleted file mode 100644 index a7a09f2..0000000 --- a/src/main/scala/termware/UnattributedTermOps.scala +++ /dev/null @@ -1,14 +0,0 @@ -package termware - -trait UnattributedTermOps -{ - this: UnattributedTerm => - - def isAttributed: Boolean = false - - def attributes: Map[Name,Term] = Map() - - def isSystemized: Boolean = false - - def termSystem: TermSystem = FreeTermSystem -} diff --git a/src/main/scala/termware/VarTermOps.scala b/src/main/scala/termware/VarTermOps.scala new file mode 100644 index 0000000..d406548 --- /dev/null +++ b/src/main/scala/termware/VarTermOps.scala @@ -0,0 +1,11 @@ +package termware + +trait VarTermOps extends TermEmptyComponents +{ + this: Term => + + override def isVar = true + + override def isScoped = scope.isDefined + +} From 73d18cfb9c7709981dde39dfa35f876cab87c668 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 21 Nov 2015 20:20:58 +0200 Subject: [PATCH 14/27] propagate termSystem and attributes throught all term types. --- src/main/scala/termware/Term.scala | 51 ++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index ed0f3df..729b451 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -7,45 +7,64 @@ sealed trait Term extends TermOps val termSystem: TermSystem = FreeTermSystem } -class AtomTerm(value:String, +case class AtomTerm(value:String, override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem) extends Term with AtomTermOps + override val termSystem: TermSystem = FreeTermSystem + ) extends Term with AtomTermOps { - val name = AtomName(value) + override val name = AtomName(value) } sealed trait PrimitiveTerm extends Term with PrimitiveTermOps -class StringTerm(value:String) extends PrimitiveTerm with StringTermOps +case class StringTerm(value:String, + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem + ) extends PrimitiveTerm with StringTermOps { - val name = StringName(value) + override val name = StringName(value) } -class CharTerm(value:Character) extends PrimitiveTerm with CharTermOps +case class CharTerm(value:Character, + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem + ) extends PrimitiveTerm with CharTermOps { - val name = CharName(value) + override val name = CharName(value) } sealed trait NumericTerm extends PrimitiveTerm with NumericTermOps -class Int32Term(value:Int) extends NumericTerm with Int32TermOps +case class Int32Term(value:Int, + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem + ) extends NumericTerm with Int32TermOps { - val name = IntName(value) + override val name = IntName(value) } -class Int64Term(value: Long) extends NumericTerm with Int64TermOps +case class Int64Term(value: Long, + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem + ) extends NumericTerm with Int64TermOps { - val name = LongName(value) + override val name = LongName(value) } -class DoubleTerm(value: Double) extends NumericTerm with DoubleTermOps +case class DoubleTerm(value: Double, + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem + ) extends NumericTerm with DoubleTermOps { - val name = DoubleName(value) + override val name = DoubleName(value) } -case class OpaqueTerm(value: Array[Byte]) extends PrimitiveTerm with OpaqueTermOps +case class OpaqueTerm(value: Array[Byte], + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem + ) extends PrimitiveTerm with OpaqueTermOps { - val name = OpaqueName(value) + override val name = OpaqueName(value) } case class StructuredTerm(termStructure: TermStructure, @@ -55,7 +74,7 @@ case class StructuredTerm(termStructure: TermStructure, override val termSystem: TermSystem = FreeTermSystem ) extends Term with StructuredTermOps -class VarTerm(val name: Name, +case class VarTerm(val name: Name, override val scope: Option[Term] = None, override val attributes: Map[Name,Term] = Map(), override val termSystem: TermSystem = FreeTermSystem From 0e1e843c1a6ec9abe9af115ba90d5208f2cb4b9b Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 21 Nov 2015 20:54:18 +0200 Subject: [PATCH 15/27] added 'empty' term-structure. --- src/main/scala/termware/FreeTermStructure.scala | 16 ++++++++++++++++ src/main/scala/termware/PrimitiveTermOps.scala | 4 +++- src/main/scala/termware/StructuredTermOps.scala | 6 ++++-- src/main/scala/termware/Term.scala | 9 ++++++++- .../scala/termware/TermEmptyComponents.scala | 10 ++++++---- src/main/scala/termware/TermOps.scala | 4 +++- src/main/scala/termware/TermStructure.scala | 11 +++++++++-- 7 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 src/main/scala/termware/FreeTermStructure.scala diff --git a/src/main/scala/termware/FreeTermStructure.scala b/src/main/scala/termware/FreeTermStructure.scala new file mode 100644 index 0000000..87f879b --- /dev/null +++ b/src/main/scala/termware/FreeTermStructure.scala @@ -0,0 +1,16 @@ +package termware + +case class FreeTermStructure(override val name:Name) extends TermStructure +{ + + override def componentIndex(name: Name): Option[Int] = + name match { + case IntName(i) => Some(i) + case _ => None + } + + override def componentName(i: Int): Option[Name] = + Some(IntName(i)) + +} + diff --git a/src/main/scala/termware/PrimitiveTermOps.scala b/src/main/scala/termware/PrimitiveTermOps.scala index 4d05347..87355ec 100644 --- a/src/main/scala/termware/PrimitiveTermOps.scala +++ b/src/main/scala/termware/PrimitiveTermOps.scala @@ -11,7 +11,9 @@ trait PrimitiveTermOps override def component(i:Int) = None - override def componentNames : IndexedSeq[Name] = IndexedSeq() + override def componentName(i:Int) = None + + override def componentIndex(n:Name) = None override def isVar = false diff --git a/src/main/scala/termware/StructuredTermOps.scala b/src/main/scala/termware/StructuredTermOps.scala index f4cdb6f..0e445b4 100644 --- a/src/main/scala/termware/StructuredTermOps.scala +++ b/src/main/scala/termware/StructuredTermOps.scala @@ -10,13 +10,15 @@ trait StructuredTermOps extends TermOps override def name = termStructure.name - override def componentNames = termStructure.componentNames + override def componentName(i:Int) = termStructure.componentName(i) + + override def componentIndex(n:Name) = termStructure.componentIndex(n) override def component(i:Int) = if (i < components.length) { Some(components(i)) } else None - override def component(n:Name) = termStructure.componentIndexes.get(n) map(components(_)) + override def component(n:Name) = termStructure.componentIndex(n) map(components(_)) override def isVar: Boolean = false diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 729b451..0f62048 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -67,13 +67,20 @@ case class OpaqueTerm(value: Array[Byte], override val name = OpaqueName(value) } -case class StructuredTerm(termStructure: TermStructure, +case class StructuredTerm( + termStructure: TermStructure, components: IndexedSeq[Term], override val scope: Option[Term] = None, override val attributes: Map[Name,Term] = Map(), override val termSystem: TermSystem = FreeTermSystem ) extends Term with StructuredTermOps +object StructuredTerm +{ + def apply(n:Name, components: IndexedSeq[Term]): StructuredTerm = + StructuredTerm(FreeTermStructure(n),components) +} + case class VarTerm(val name: Name, override val scope: Option[Term] = None, override val attributes: Map[Name,Term] = Map(), diff --git a/src/main/scala/termware/TermEmptyComponents.scala b/src/main/scala/termware/TermEmptyComponents.scala index 4108c36..bdd2fcd 100644 --- a/src/main/scala/termware/TermEmptyComponents.scala +++ b/src/main/scala/termware/TermEmptyComponents.scala @@ -6,13 +6,15 @@ trait TermEmptyComponents this: Term => - def arity = 0 + override def arity = 0 - def component(n:Name) = None + override def component(n:Name) = None - def component(i:Int) = None + override def component(i:Int) = None - def componentNames:IndexedSeq[Name] = IndexedSeq() + override def componentName(i:Int) = None + + override def componentIndex(n:Name) = None } diff --git a/src/main/scala/termware/TermOps.scala b/src/main/scala/termware/TermOps.scala index eaf90f6..a672c34 100644 --- a/src/main/scala/termware/TermOps.scala +++ b/src/main/scala/termware/TermOps.scala @@ -8,7 +8,9 @@ trait TermOps def arity: Int - def componentNames: IndexedSeq[Name] + def componentName(i:Int): Option[Name] + + def componentIndex(n:Name): Option[Int] def component(i: Int): Option[Term] diff --git a/src/main/scala/termware/TermStructure.scala b/src/main/scala/termware/TermStructure.scala index 4e8dca2..be2d5b1 100644 --- a/src/main/scala/termware/TermStructure.scala +++ b/src/main/scala/termware/TermStructure.scala @@ -4,9 +4,9 @@ trait TermStructure { def name: Name - def componentIndexes: Map[Name,Int] + def componentIndex(name:Name): Option[Int] - def componentNames: IndexedSeq[Name] + def componentName(i: Int): Option[Name] } case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) extends TermStructure @@ -14,4 +14,11 @@ case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) ext val componentIndexes = componentNames.foldLeft(Map[Name,Int]()){ (s,e) => s.updated(e,s.size+1) } + override def componentIndex(name:Name): Option[Int] = componentIndexes.get(name) + + override def componentName(i:Int): Option[Name] = + if (i < componentNames.size) { + Some(componentNames(i)) + } else None + } From f60c3dca07954064053cb77374be6ac09ec18c06 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Wed, 25 Nov 2015 13:47:09 +0200 Subject: [PATCH 16/27] added bib --- doc/stermware.bib | 28 +++++++++++++++++++ doc/stermware.tex | 44 ++++++++++++++++++++++++++---- src/main/scala/termware/Term.scala | 2 ++ 3 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 doc/stermware.bib diff --git a/doc/stermware.bib b/doc/stermware.bib new file mode 100644 index 0000000..0e21df3 --- /dev/null +++ b/doc/stermware.bib @@ -0,0 +1,28 @@ + + + + +@article{DBLP:journals/fuin/DoroshenkoS06, + author = {Anatoly E. Doroshenko and + Ruslan Shevchenko}, + title = {TermWare: A Rewriting Framework for Rule-Based Programming Dynamic Applications}, + journal = {Fundam. Inform.}, + volume = {72}, + number = {1-3}, + pages = {95--108}, + year = {2006}, + url = {http://content.iospress.com/articles/fundamenta-informaticae/fi72-1-3-08}, + timestamp = {Mon, 18 May 2015 17:23:19 +0200}, + biburl = {http://dblp.uni-trier.de/rec/bib/journals/fuin/DoroshenkoS06}, + bibsource = {dblp computer science bibliography, http://dblp.org} +} + +@INPROCEEDINGS{Jay05purepattern, + author = {C. Barry Jay and Delia Kesner}, + title = {Pure Pattern Calculus}, + booktitle = {ACM Trans. Program. Lang. Syst}, + year = {2005}, + pages = {262--274}, + url = {http://www.pps.univ-paris-diderot.fr/~kesner/papers/revisedpurepattern.pdf} +} + diff --git a/doc/stermware.tex b/doc/stermware.tex index d7dbdde..6ec5f78 100644 --- a/doc/stermware.tex +++ b/doc/stermware.tex @@ -40,12 +40,12 @@ \section{Motivation} - Rule-based deduction and rewriting is well known + Rule-based deduction and rewriting is a well known formal method techniques. - Let we have some big structure with some semantics, which can be expressed as expression in some DSL (in case of source code - analysis -- analysed language) - Rule rewriting allow to discover patternsm + + + \section{Basic definitions} @@ -57,10 +57,44 @@ \section{Basic definitions} \item variable terms $x_{i}$ which can be inside variable-bound terms. \item variable bounds term, i.e. so-called 'with-expressions': $with(x_1,\dots x_n):t$ \item let terms, i.e. so-called 'let expressions' $let \{ x_i \leftarrow t_i \}_{1\dots n} t \in T$ - \item rule terms, i. e. so-called 'rule expressions': $ruleset(p_1 \to r_1 ; p_2 \to r_2; .. p_n => r_n)$ + \item rule terms, i. e. so-called 'rule expressions': + $rule(p_1 ; p_2 ; \dots p_n \to r_n : p_{fail})$ + \item application $a b$ \end{itemize} + Let's define usual term operations: + \begin{itemize} + \item s contains t: $s \cap t$ + \end{itemize} + + Transformations: + +\begin{itemize} + \item application reduction + $$ rule(with(x_i):p_i \to r_i, ... ) q = + \left\{\begin{array}{l l} + \sigma r_i & if \; \sigma=unify(p_i,q)/x_{i} \\ + p_{fail} & otherwise \\ + \end{array} + \right\} + $$ + \item with propagation + $$ with(x):rule(p_1 \dots p_{n}, p_{fail}) = + rule(with(x,p_1) \dots with(x,p_{n}), with(p_{fail})) = + $$ + \item with chaining + $$ with(x_1 \dots x_n):with(y_1 \dots y_n):p = + with(x_1 \dots x_n, y_1 \dots y_n):p $$ + \item with variable elimination + $$ with(x_{1} \dots x_{i} \dots x_{n}):p = + with(x_{1} \dots x_{i-1}, x_{i+1}, \dots x_{n})p \; if x_i \not\in p $$ +\end{itemize} + + +\section{Related work} + Pure pattern calculus \cite{Jay05purepattern} is a most close formal system. It's congruent by + price of not \bibliographystyle{abbrv} \bibliography{stermware} diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 0f62048..6949270 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -67,6 +67,7 @@ case class OpaqueTerm(value: Array[Byte], override val name = OpaqueName(value) } +// TODO: add min/max index. case class StructuredTerm( termStructure: TermStructure, components: IndexedSeq[Term], @@ -82,6 +83,7 @@ object StructuredTerm } case class VarTerm(val name: Name, + val index: Int, override val scope: Option[Term] = None, override val attributes: Map[Name,Term] = Map(), override val termSystem: TermSystem = FreeTermSystem From 659b38c770ea41b344989d7249eb79cc9a519bb5 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 26 Dec 2015 16:53:35 +0200 Subject: [PATCH 17/27] new conpact version for serialization in progress --- doc/stermware.bib | 9 +- doc/stermware.tex | 3 +- src/main/scala/termware/FreeTermSystem.scala | 6 +- src/main/scala/termware/Match.scala | 49 +++++ .../scala/termware/StructuredTermOps.scala | 4 +- src/main/scala/termware/Term.scala | 25 ++- src/main/scala/termware/TermAttributes.scala | 9 +- src/main/scala/termware/TermOps.scala | 2 + src/main/scala/termware/TermSerializer.scala | 12 ++ src/main/scala/termware/TermStorage.scala | 11 + src/main/scala/termware/TermSystem.scala | 11 +- src/main/scala/termware/Unification.scala | 8 + src/main/scala/termware/free/Serializer.scala | 203 ++++++++++++++++++ .../scala/termware/free/Unification.scala | 136 ++++++++++++ src/main/scala/termware/util/Input.scala | 51 +++++ src/main/scala/termware/util/Output.scala | 57 +++++ 16 files changed, 582 insertions(+), 14 deletions(-) create mode 100644 src/main/scala/termware/Match.scala create mode 100644 src/main/scala/termware/TermSerializer.scala create mode 100644 src/main/scala/termware/TermStorage.scala create mode 100644 src/main/scala/termware/Unification.scala create mode 100644 src/main/scala/termware/free/Serializer.scala create mode 100644 src/main/scala/termware/free/Unification.scala create mode 100644 src/main/scala/termware/util/Input.scala create mode 100644 src/main/scala/termware/util/Output.scala diff --git a/doc/stermware.bib b/doc/stermware.bib index 0e21df3..a94ad94 100644 --- a/doc/stermware.bib +++ b/doc/stermware.bib @@ -1,5 +1,12 @@ - +@ARTICLE{Klop93combinatoryreduction, + author = {Jan Willem Klop and Vincent van Oostrom and Femke van Raamsdonk}, + title = {Combinatory Reduction Systems: introduction and survey}, + journal = {THEORETICAL COMPUTER SCIENCE}, + year = {1993}, + volume = {121}, + pages = {279--308} +} @article{DBLP:journals/fuin/DoroshenkoS06, diff --git a/doc/stermware.tex b/doc/stermware.tex index 6ec5f78..bdd16b4 100644 --- a/doc/stermware.tex +++ b/doc/stermware.tex @@ -40,7 +40,8 @@ \section{Motivation} - Rule-based deduction and rewriting is a well known formal method techniques. + Rule-based deduction and rewriting is a well known techniques. Exists many formalizations, from + to $\rho$-caclulus and pure pattern calculus; and diff --git a/src/main/scala/termware/FreeTermSystem.scala b/src/main/scala/termware/FreeTermSystem.scala index af4af60..b05b880 100644 --- a/src/main/scala/termware/FreeTermSystem.scala +++ b/src/main/scala/termware/FreeTermSystem.scala @@ -6,11 +6,11 @@ object FreeTermSystem extends TermSystem def name: Term = new AtomTerm("Free") - def adopt(t: Term): Term = t + override def adopt(t: Term): Term = t - def mergeAttributes(attrName: Name, x:Term, y:Term): Term = ??? + override def unification: Unification = free.Unification - def isFree: Boolean = true + override def isFree: Boolean = true } diff --git a/src/main/scala/termware/Match.scala b/src/main/scala/termware/Match.scala new file mode 100644 index 0000000..1ca3402 --- /dev/null +++ b/src/main/scala/termware/Match.scala @@ -0,0 +1,49 @@ +package termware + +sealed trait Match +{ + def put(x:Term,y:Term, u: Unification, s: Term): Match + + // ts ? + def merge(x: Match, u: Unification, s:Term): Match +} + +case class Substitution(mapping: Map[Term,Term]) extends Match +{ + + def put(x:Term, y:Term, u: Unification, s: Term): Match = + { + def updated = Substitution(mapping.updated(x,y)) + mapping.get(x) match { + case Some(z) => u(y,z,s) match { + case yz@Substitution(_) => updated.merge(yz,u,s) + case f@MatchFailure(_,_,_) => f + } + case None => updated + } + } + + def merge(x: Match, u: Unification, scope: Term): Match = + x match { + case Substitution(xm) => + val s0: Match = this + xm.foldLeft(s0){ (s,e) => s.put(e._1,e._2,u,scope) } + case f@MatchFailure(_,_,_) => f + } + +} + +case class MatchFailure(val x: Term, val y: Term, val reason: String) extends Match +{ + + def put(x:Term,y:Term, u: Unification, s: Term): Match = this + + def merge(x: Match, u: Unification, s:Term ): Match = this + +} + +object Substitution +{ + val empty = Substitution(Map()) +} + diff --git a/src/main/scala/termware/StructuredTermOps.scala b/src/main/scala/termware/StructuredTermOps.scala index 0e445b4..a0b9ffd 100644 --- a/src/main/scala/termware/StructuredTermOps.scala +++ b/src/main/scala/termware/StructuredTermOps.scala @@ -22,6 +22,8 @@ trait StructuredTermOps extends TermOps override def isVar: Boolean = false - override def isScoped = scope.isDefined + override def scope = None + + override def isScoped = false } diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 6949270..19840b4 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -5,6 +5,7 @@ sealed trait Term extends TermOps { val attributes: Map[Name,Term] = Map() val termSystem: TermSystem = FreeTermSystem + } case class AtomTerm(value:String, @@ -13,16 +14,25 @@ case class AtomTerm(value:String, ) extends Term with AtomTermOps { override val name = AtomName(value) + + override def withAttributes(newAttributes: Map[Name,Term]) = + copy(attributes = newAttributes) + } sealed trait PrimitiveTerm extends Term with PrimitiveTermOps + case class StringTerm(value:String, override val attributes: Map[Name,Term] = Map(), override val termSystem: TermSystem = FreeTermSystem ) extends PrimitiveTerm with StringTermOps { override val name = StringName(value) + + override def withAttributes(newAttributes: Map[Name,Term]) = + copy(attributes = newAttributes) + } case class CharTerm(value:Character, @@ -31,6 +41,10 @@ case class CharTerm(value:Character, ) extends PrimitiveTerm with CharTermOps { override val name = CharName(value) + + override def withAttributes(newAttributes: Map[Name,Term]) = + copy(attributes = newAttributes) + } sealed trait NumericTerm extends PrimitiveTerm with NumericTermOps @@ -41,6 +55,7 @@ case class Int32Term(value:Int, ) extends NumericTerm with Int32TermOps { override val name = IntName(value) + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } case class Int64Term(value: Long, @@ -49,6 +64,7 @@ case class Int64Term(value: Long, ) extends NumericTerm with Int64TermOps { override val name = LongName(value) + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } case class DoubleTerm(value: Double, @@ -57,6 +73,7 @@ case class DoubleTerm(value: Double, ) extends NumericTerm with DoubleTermOps { override val name = DoubleName(value) + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } case class OpaqueTerm(value: Array[Byte], @@ -65,16 +82,19 @@ case class OpaqueTerm(value: Array[Byte], ) extends PrimitiveTerm with OpaqueTermOps { override val name = OpaqueName(value) + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } // TODO: add min/max index. case class StructuredTerm( termStructure: TermStructure, components: IndexedSeq[Term], - override val scope: Option[Term] = None, override val attributes: Map[Name,Term] = Map(), override val termSystem: TermSystem = FreeTermSystem ) extends Term with StructuredTermOps +{ + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) +} object StructuredTerm { @@ -88,5 +108,8 @@ case class VarTerm(val name: Name, override val attributes: Map[Name,Term] = Map(), override val termSystem: TermSystem = FreeTermSystem ) extends Term with VarTermOps +{ + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) +} diff --git a/src/main/scala/termware/TermAttributes.scala b/src/main/scala/termware/TermAttributes.scala index 92540a3..1762d6a 100644 --- a/src/main/scala/termware/TermAttributes.scala +++ b/src/main/scala/termware/TermAttributes.scala @@ -1,8 +1,11 @@ package termware +trait TermAttributed[X] { -trait TermAttributes -{ - this: Term => +} +object TermAttributes +{ + val empty: Map[Name,Term] = Map() } + diff --git a/src/main/scala/termware/TermOps.scala b/src/main/scala/termware/TermOps.scala index a672c34..7f67aad 100644 --- a/src/main/scala/termware/TermOps.scala +++ b/src/main/scala/termware/TermOps.scala @@ -22,4 +22,6 @@ trait TermOps def isVar: Boolean + def withAttributes(attributes: Map[Name,Term]): Term + } diff --git a/src/main/scala/termware/TermSerializer.scala b/src/main/scala/termware/TermSerializer.scala new file mode 100644 index 0000000..28479d1 --- /dev/null +++ b/src/main/scala/termware/TermSerializer.scala @@ -0,0 +1,12 @@ +package termware + +import util._ + +trait TermSerializer +{ + + def apply(t: Term, out: Output): Unit + + def unapply(input: Input): Term + +} diff --git a/src/main/scala/termware/TermStorage.scala b/src/main/scala/termware/TermStorage.scala new file mode 100644 index 0000000..a58fe8c --- /dev/null +++ b/src/main/scala/termware/TermStorage.scala @@ -0,0 +1,11 @@ +package termware + + +trait TermStorage +{ + + def read(path: String): Term + + def write(path: String, t: Term): Unit + +} diff --git a/src/main/scala/termware/TermSystem.scala b/src/main/scala/termware/TermSystem.scala index 7d16d41..3d50dae 100644 --- a/src/main/scala/termware/TermSystem.scala +++ b/src/main/scala/termware/TermSystem.scala @@ -3,13 +3,16 @@ package termware trait TermSystem { - def name: Term - def adopt(t: Term): Term + def adopt(t: Term): Term = t + + def unification: Unification = free.Unification + + def storage: TermStorage = ??? - def mergeAttributes(attrName: Name, x:Term, y:Term): Term + def serializer: TermSerializer = free.Serializer - def isFree: Boolean + def isFree: Boolean = false } diff --git a/src/main/scala/termware/Unification.scala b/src/main/scala/termware/Unification.scala new file mode 100644 index 0000000..6a764f9 --- /dev/null +++ b/src/main/scala/termware/Unification.scala @@ -0,0 +1,8 @@ +package termware + +trait Unification +{ + + def apply(x: Term, y: Term, scope:Term): Match + +} diff --git a/src/main/scala/termware/free/Serializer.scala b/src/main/scala/termware/free/Serializer.scala new file mode 100644 index 0000000..2dad6af --- /dev/null +++ b/src/main/scala/termware/free/Serializer.scala @@ -0,0 +1,203 @@ +package termware.free + +import java.nio._ +import termware._ +import termware.util._ +import termware.TermAttributes.{empty=>emptyAttributes} + +// TODO: write input pos on error. + +trait Serializer extends TermSerializer +{ + + def apply(t: Term, out: Output): Unit = ??? + + def unapply(input: Input): Term = ??? + + def termSystem: TermSystem + + + case class BlockContext( + val structures: Map[Int, TermStructure] = Map(), + val invStructures: Map[TermStructure, Int] = Map(), + val structureIndex: Int = 0, + val scopes: Map[Int, Term] = Map(), + val invScopes: Map[Term,Int] = Map(), + val scopeIndex: Int = 0 + ) { + + def withStructure(structure: TermStructure): BlockContext = + { + invStructures.get(structure) match { + case None => val si = structureIndex+1 + copy(structures = structures.updated(si, structure), + invStructures = invStructures.updated(structure,si), + structureIndex = si) + case Some(si) => this + } + } + + def withScope(scope: Term): BlockContext = + { + invScopes.get(scope) match { + case None => + val si = scopeIndex+1 + copy(scopes = scopes.updated(si,scope), + invScopes = invScopes.updated(scope,si), + scopeIndex = si) + case Some(_) => this + } + } + + } + + + final val TAG_TERM = 100 + final val TAG_TERMSTRUCTURE = 101 + final val TAG_ATTRIBUTES = 102 + + final val TAG_END = 400 + + + + final val TAG_ATOM = 1; + final val TAG_STRUCTURED=2; + final val TAG_VAR = 3; + + final val TAG_PRIMITIVE = 0x1000; + + + private def writeTerm(t: Term, bc: BlockContext, out: Output): BlockContext = + { + val nbc0 = t match { + case a: AtomTerm => out << TAG_ATOM << a.value ; bc + case p: PrimitiveTerm => writePrimitive(p,out) + case s: StructuredTerm => writeStructured(s,bc,out) + case v: VarTerm => writeVar(v,bc,out) + } + writeAttributes(t.attributes,bc,out) + } + + private def readTerm(in: Input, bc: BlockContext): (Term, BlockContext) = + { + val tag = in.readInt + val (t,nbc0) = tag match { + case TAG_ATOM => (AtomTerm(in.readString,Map(),termSystem),bc) + case TAG_STRUCTURED => readStructured(in, bc) + case TAG_TERMSTRUCTURE => readTerm(in,readTermStructure(in,bc)) + case TAG_VAR => readVar(in,bc) + case x if ((x|TAG_PRIMITIVE)!=0) => (readPrimitive(x,in), bc) + case _ => throw new IllegalStateException("Invalid term tag:"+tag) + } + val (attributes, nbc) = readAttributes(in,nbc0) + (t withAttributes attributes, nbc) + } + + + private def writePrimitive(p: PrimitiveTerm, out: Output): Unit = + { + out << (TAG_PRIMITIVE | p.name.typeIndex) + p match { + case StringTerm(v,_,_) => out << v + case CharTerm(v,_,_) => out << v + case Int32Term(v,_,_) => out << v + case Int64Term(v,_,_) => out << v + case DoubleTerm(v,_,_) => out << v + case OpaqueTerm(v,_,_) => (out << v.size).write(v) + } + } + + private def readPrimitive(tag: Int, in: Input): PrimitiveTerm = + { + import NameTypeIndexes._ + (tag & (~TAG_PRIMITIVE)) match { + case STRING => StringTerm(in.readString,Map(),termSystem) + case CHAR => CharTerm(in.readChar,Map(),termSystem) + case INT => Int32Term(in.readInt,Map(),termSystem) + case LONG => Int64Term(in.readLong,Map(),termSystem) + case DOUBLE => DoubleTerm(in.readDouble(),Map(),termSystem) + case OPAQUE => OpaqueTerm(in.readOpaque(),Map(),termSystem) + case _ => throw new IllegalStateException("Invalid primitive tag: "+tag) + } + } + + private def writeStructured(t: StructuredTerm, bc: BlockContext, out: Output): BlockContext = + { + val ts = t.termStructure; + val nbc0 = bc.invStructures.get(ts) match { + case Some(tsi) => bc + case None => + val newTsi = bc.structureIndex+1 + val newTs = bc.structures.updated(newTsi,ts) + val newInvTs = bc.invStructures.updated(ts, newTsi) + out.writeInt(TAG_TERMSTRUCTURE) + writeStructure(ts,bc,out) + bc.copy(structures=newTs, invStructures=newInvTs, structureIndex=newTsi) + } + val newScopeIndex = bc.scopeIndex+1 + val newScopes = bc.scopes.updated(newScopeIndex,t) + val newInvScopes = bc.invScopes.updated(t,newScopeIndex) + val nbc = nbc0.copy(scopes=newScopes, invScopes=newInvScopes, scopeIndex=newScopeIndex) + out.writeInt(TAG_STRUCTURED) + out.writeInt(nbc.structureIndex) + out.writeInt(t.arity) + t.components.foldLeft(nbc) { (s,e) => + writeTerm(e,s,out) + } + } + + private def readStructured(in: Input, bc: BlockContext): (Term, BlockContext) = + { + val tsi = in.readInt + val ts: TermStructure = bc.structures.getOrElse(tsi,throw new IllegalStateException( + "invalid structure index ")) + val arity = in.readInt + val subterms = new Array[Term](arity) + var cbc = bc + for(i <- (0 until arity)) { + val (t, nbc) = readTerm(in, cbc) + subterms(i)=t + cbc = nbc + } + (StructuredTerm(ts,subterms.toIndexedSeq,emptyAttributes,termSystem), cbc) + } + + private def writeVar(t: VarTerm, bc: BlockContext, out: Output): BlockContext = + { + val scopeIndex = t.scope match { + case Some(u) => bc.invScopes.getOrElse(u, + throw new IllegalStateException("scope not found in uplevel")) + case None => -1 + } + out.writeInt(scopeIndex) + bc + } + + private def readVar(in: Input, bc: BlockContext): (VarTerm, BlockContext) = ??? + + private def writeName(name:Name, out: Output): Unit = ??? + + private def readName(in: Input): Name = ??? + + private def writeAttributes(attributes: Map[Name,Term], bc: BlockContext, out: Output): BlockContext = + { + out.writeInt(attributes.size) + attributes.foldLeft(bc){ (s,e) => + writeName(e._1,out) + writeTerm(e._2,s,out) + } + } + + private def readAttributes(in: Input, bc: BlockContext): (Map[Name,Term], BlockContext) = ??? + + private def writeStructure(ts: TermStructure, bc: BlockContext, out: Output): BlockContext = ??? + + private def readTermStructure(in: Input, bc: BlockContext): BlockContext = ??? + + +} + +object Serializer extends Serializer +{ + def termSystem = FreeTermSystem +} diff --git a/src/main/scala/termware/free/Unification.scala b/src/main/scala/termware/free/Unification.scala new file mode 100644 index 0000000..bc75cb7 --- /dev/null +++ b/src/main/scala/termware/free/Unification.scala @@ -0,0 +1,136 @@ +package termware.free + +import termware._ + +object Unification extends termware.Unification +{ + + // naive recursive implementation. + // TODO: rewrite + def apply(x: Term, y: Term, scope: Term): Match = + { + x match { + case AtomTerm(xv,xa,xts) => + y match { + case AtomTerm(yv,ya,yts) => + if (xv == yv) { + Substitution.empty + } else { + MatchFailure(x,y,"different atoms") + } + case VarTerm(yn,yi,ys,xa,ts) => + if (ys.forall(_ eq scope)) { + Substitution(Map(y->x)) + } else { + MatchFailure(x,y,"can't unify atom and non-with var") + } + case _ => + MatchFailure(x,y,"can't unify atom with non-atom") + } + case px:PrimitiveTerm => + y match { + case py:PrimitiveTerm => applyPrimitive(px,py) + case VarTerm(yn,yi,ys,xa,ts) => + if (ys.forall(_ eq scope)) { + Substitution(Map(y->x)) + } else { + MatchFailure(x,y,"can't unify primitive and non-with var") + } + case _ => + MatchFailure(x,y,"can't unify primitive with non-primitive") + } + case StructuredTerm(xstructure,xcomponents,xa,xts) => + y match { + case StructuredTerm(ystructure,ycomponents,ya,yts) => + if (ystructure.name != ystructure.name) { + MatchFailure(x,y,"name mismatch") + } else if (xcomponents.length != ycomponents.length) { + MatchFailure(x,y,"arity mismatch") + } else { + var s0: Match = Substitution.empty + (xcomponents zip ycomponents).foldLeft(s0){ (s,e) => + s.merge(apply(e._1,e._2,scope),this,scope) } + } + case VarTerm(yn,yi,ys,xa,ts) => + if (ys.forall(_ eq scope)) { + Substitution(Map(y->x)) + } else { + MatchFailure(x,y,"can't unify structured term and non-with var") + } + case _ => + MatchFailure(x,y,"structure mismatch") + } + case VarTerm(xn,xi,xs,xa,ts) => + if (xs.forall(_ eq scope)) { + Substitution(Map(x->y)) + } else { + y match { + case VarTerm(yn,yi,ys,xa,ts) => + if (ys.forall(_ eq scope)) { + Substitution(Map(y->x)) + } else if (ys.get eq xs.get) { + Substitution.empty + } else { + MatchFailure(x,y,"var mismatch") + } + case _ => + MatchFailure(x,y,"var mismatch") + } + } + } + } + + def applyPrimitive(x: PrimitiveTerm, y: PrimitiveTerm): Match = + x match { + case StringTerm(xv,xa,xts) => + y match { + case StringTerm(yv,ya,yts) => + if (xv == yv) Substitution.empty + else MatchFailure(x,y,"string mismatch") + case _ => + MatchFailure(x,y,"type mismatch") + } + case CharTerm(xv,xa,xts) => + y match { + case CharTerm(yv,ya,yts) => + if (xv == yv) Substitution.empty + else MatchFailure(x,y,"char mismatch") + case _ => + MatchFailure(x,y,"type mismatch") + } + case Int32Term(xv,xa,xts) => + y match { + case Int32Term(yv,ya,yts) => + if (xv == yv) Substitution.empty + else MatchFailure(x,y,"int32 mismatch") + case _ => + MatchFailure(x,y,"type mismatch") + } + case Int64Term(xv,xa,xts) => + y match { + case Int64Term(yv,ya,yts) => + if (xv == yv) Substitution.empty + else MatchFailure(x,y,"int64 mismatch") + case _ => + MatchFailure(x,y,"type mismatch") + } + case DoubleTerm(xv,xa,xts) => + y match { + case DoubleTerm(yv,ya,yts) => + if (xv == yv) Substitution.empty + else MatchFailure(x,y,"double mismatch") + case _ => + MatchFailure(x,y,"type mismatch") + } + case OpaqueTerm(xv,xa,xts) => + y match { + case OpaqueTerm(yv,ya,yts) => + if (xv == yv) Substitution.empty + else MatchFailure(x,y,"double mismatch") + case _ => + MatchFailure(x,y,"type mismatch") + } + } + +} + diff --git a/src/main/scala/termware/util/Input.scala b/src/main/scala/termware/util/Input.scala new file mode 100644 index 0000000..af8a84a --- /dev/null +++ b/src/main/scala/termware/util/Input.scala @@ -0,0 +1,51 @@ +package termware.util + +import java.nio.charset.StandardCharsets + +trait Input +{ + + def read(bytes: Array[Byte]):Int + + def readByte(): Byte + + def readInt():Int = + { + val v0 = readByte + val v1 = readByte + val v2 = readByte + val v3 = readByte + (((v0 << 8 + v1) << 8) + v2)<<8 + v3 + } + + def readChar():Char = + readInt.toChar + + def readLong(): Long = + { + val v0 = readInt + val v1 = readInt + (v0.toLong << 32) | v1 + } + + def readDouble(): Double = + java.lang.Double.longBitsToDouble(readLong) + + def readString(): String = + { + val bytes = readOpaque + new String(bytes,StandardCharsets.UTF_8) + } + + def readOpaque(): Array[Byte] = + { + val length = readInt + val bytes = new Array[Byte](length) + val n = read(bytes) + if (n> 24).toByte) + write((v >> 16).toByte) + write((v >> 8).toByte ) + write((v ).toByte ) + this + } + + def <<(v:Int): this.type = writeInt(v) + + def writeLong(v:Long): this.type = + { + writeInt( (v>>32).toInt ).writeInt( (v & 0xFFFFFFFF).toInt ) + } + + def <<(v:Long): this.type = writeLong(v) + + def writeString(s: String): this.type = + { + val bytes = s.getBytes(StandardCharsets.UTF_8) + writeInt(bytes.length).write(bytes) + this + } + + def <<(s:String): this.type = writeString(s) + + def writeDouble(v:Double): this.type = + writeLong(java.lang.Double.doubleToLongBits(v)) + + def <<(v:Double): this.type = writeDouble(v) + +} + + +object Output +{ + + +} From 8d7ad010548b93ea56ea14efd021df44c8c9782c Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 26 Dec 2015 17:17:06 +0200 Subject: [PATCH 18/27] boilterpalte withAttibute moved to Ops definitions. --- src/main/scala/termware/AtomTermOps.scala | 2 ++ src/main/scala/termware/CharTermOps.scala | 5 ++++- src/main/scala/termware/DoubleTermOps.scala | 2 ++ src/main/scala/termware/Int32TermOps.scala | 2 ++ src/main/scala/termware/Int64TermOps.scala | 2 ++ src/main/scala/termware/OpaqueTermOps.scala | 1 + src/main/scala/termware/PrimitiveTermOps.scala | 1 + src/main/scala/termware/StringTermOps.scala | 2 ++ .../scala/termware/StructuredTermOps.scala | 2 ++ src/main/scala/termware/Term.scala | 18 ------------------ src/main/scala/termware/VarTermOps.scala | 4 +++- 11 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/scala/termware/AtomTermOps.scala b/src/main/scala/termware/AtomTermOps.scala index 149ecde..c485aaf 100644 --- a/src/main/scala/termware/AtomTermOps.scala +++ b/src/main/scala/termware/AtomTermOps.scala @@ -12,5 +12,7 @@ trait AtomTermOps extends TermEmptyComponents override def isVar = false + override def withAttributes(newAttributes: Map[Name,Term]) = + copy(attributes = newAttributes) } diff --git a/src/main/scala/termware/CharTermOps.scala b/src/main/scala/termware/CharTermOps.scala index f175d7b..62e80eb 100644 --- a/src/main/scala/termware/CharTermOps.scala +++ b/src/main/scala/termware/CharTermOps.scala @@ -2,6 +2,9 @@ package termware trait CharTermOps { - this: Term => + this: CharTerm => + + override def withAttributes(newAttributes: Map[Name,Term]) = + copy(attributes = newAttributes) } diff --git a/src/main/scala/termware/DoubleTermOps.scala b/src/main/scala/termware/DoubleTermOps.scala index 3403366..08a847c 100644 --- a/src/main/scala/termware/DoubleTermOps.scala +++ b/src/main/scala/termware/DoubleTermOps.scala @@ -4,4 +4,6 @@ trait DoubleTermOps extends NumericTermOps { this: DoubleTerm => + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) + } diff --git a/src/main/scala/termware/Int32TermOps.scala b/src/main/scala/termware/Int32TermOps.scala index 882e0b5..1ccd7c7 100644 --- a/src/main/scala/termware/Int32TermOps.scala +++ b/src/main/scala/termware/Int32TermOps.scala @@ -4,4 +4,6 @@ trait Int32TermOps extends NumericTermOps { this: Int32Term => + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) + } diff --git a/src/main/scala/termware/Int64TermOps.scala b/src/main/scala/termware/Int64TermOps.scala index 411e900..081172e 100644 --- a/src/main/scala/termware/Int64TermOps.scala +++ b/src/main/scala/termware/Int64TermOps.scala @@ -4,4 +4,6 @@ trait Int64TermOps extends NumericTermOps { this: Int64Term => + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) + } diff --git a/src/main/scala/termware/OpaqueTermOps.scala b/src/main/scala/termware/OpaqueTermOps.scala index c316c0e..8ea33bc 100644 --- a/src/main/scala/termware/OpaqueTermOps.scala +++ b/src/main/scala/termware/OpaqueTermOps.scala @@ -6,4 +6,5 @@ trait OpaqueTermOps extends PrimitiveTermOps this: OpaqueTerm => + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } diff --git a/src/main/scala/termware/PrimitiveTermOps.scala b/src/main/scala/termware/PrimitiveTermOps.scala index 87355ec..a9f4de5 100644 --- a/src/main/scala/termware/PrimitiveTermOps.scala +++ b/src/main/scala/termware/PrimitiveTermOps.scala @@ -21,4 +21,5 @@ trait PrimitiveTermOps override def scope = None + } diff --git a/src/main/scala/termware/StringTermOps.scala b/src/main/scala/termware/StringTermOps.scala index f591176..c87413a 100644 --- a/src/main/scala/termware/StringTermOps.scala +++ b/src/main/scala/termware/StringTermOps.scala @@ -6,4 +6,6 @@ trait StringTermOps extends PrimitiveTermOps this: StringTerm => + override def withAttributes(newAttributes: Map[Name,Term]) = + copy(attributes = newAttributes) } diff --git a/src/main/scala/termware/StructuredTermOps.scala b/src/main/scala/termware/StructuredTermOps.scala index a0b9ffd..c1f4e3f 100644 --- a/src/main/scala/termware/StructuredTermOps.scala +++ b/src/main/scala/termware/StructuredTermOps.scala @@ -26,4 +26,6 @@ trait StructuredTermOps extends TermOps override def isScoped = false + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) + } diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 19840b4..61aa8ea 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -14,10 +14,6 @@ case class AtomTerm(value:String, ) extends Term with AtomTermOps { override val name = AtomName(value) - - override def withAttributes(newAttributes: Map[Name,Term]) = - copy(attributes = newAttributes) - } sealed trait PrimitiveTerm extends Term with PrimitiveTermOps @@ -29,10 +25,6 @@ case class StringTerm(value:String, ) extends PrimitiveTerm with StringTermOps { override val name = StringName(value) - - override def withAttributes(newAttributes: Map[Name,Term]) = - copy(attributes = newAttributes) - } case class CharTerm(value:Character, @@ -41,10 +33,6 @@ case class CharTerm(value:Character, ) extends PrimitiveTerm with CharTermOps { override val name = CharName(value) - - override def withAttributes(newAttributes: Map[Name,Term]) = - copy(attributes = newAttributes) - } sealed trait NumericTerm extends PrimitiveTerm with NumericTermOps @@ -55,7 +43,6 @@ case class Int32Term(value:Int, ) extends NumericTerm with Int32TermOps { override val name = IntName(value) - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } case class Int64Term(value: Long, @@ -64,7 +51,6 @@ case class Int64Term(value: Long, ) extends NumericTerm with Int64TermOps { override val name = LongName(value) - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } case class DoubleTerm(value: Double, @@ -73,7 +59,6 @@ case class DoubleTerm(value: Double, ) extends NumericTerm with DoubleTermOps { override val name = DoubleName(value) - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } case class OpaqueTerm(value: Array[Byte], @@ -82,7 +67,6 @@ case class OpaqueTerm(value: Array[Byte], ) extends PrimitiveTerm with OpaqueTermOps { override val name = OpaqueName(value) - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } // TODO: add min/max index. @@ -93,7 +77,6 @@ case class StructuredTerm( override val termSystem: TermSystem = FreeTermSystem ) extends Term with StructuredTermOps { - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } object StructuredTerm @@ -109,7 +92,6 @@ case class VarTerm(val name: Name, override val termSystem: TermSystem = FreeTermSystem ) extends Term with VarTermOps { - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } diff --git a/src/main/scala/termware/VarTermOps.scala b/src/main/scala/termware/VarTermOps.scala index d406548..4b39a4a 100644 --- a/src/main/scala/termware/VarTermOps.scala +++ b/src/main/scala/termware/VarTermOps.scala @@ -2,10 +2,12 @@ package termware trait VarTermOps extends TermEmptyComponents { - this: Term => + this: VarTerm => override def isVar = true override def isScoped = scope.isDefined + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) + } From d499aac4ff965e0c98065959abc81a74100d70e1 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 26 Dec 2015 19:29:03 +0200 Subject: [PATCH 19/27] serialization is in proggress --- src/main/scala/termware/Name.scala | 2 +- src/main/scala/termware/free/Serializer.scala | 44 +++++++++++++++++-- src/main/scala/termware/util/Output.scala | 6 +++ 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/main/scala/termware/Name.scala b/src/main/scala/termware/Name.scala index 3485081..b3a1e20 100644 --- a/src/main/scala/termware/Name.scala +++ b/src/main/scala/termware/Name.scala @@ -47,7 +47,7 @@ case class StringName(v:String) extends StringLikeName(v) def typeIndex = STRING } -sealed class CharLikeName(val value:Char) extends Name +sealed abstract class CharLikeName(val value:Char) extends Name { def typeIndex = CHAR diff --git a/src/main/scala/termware/free/Serializer.scala b/src/main/scala/termware/free/Serializer.scala index 2dad6af..1d2bdef 100644 --- a/src/main/scala/termware/free/Serializer.scala +++ b/src/main/scala/termware/free/Serializer.scala @@ -85,7 +85,7 @@ trait Serializer extends TermSerializer case TAG_ATOM => (AtomTerm(in.readString,Map(),termSystem),bc) case TAG_STRUCTURED => readStructured(in, bc) case TAG_TERMSTRUCTURE => readTerm(in,readTermStructure(in,bc)) - case TAG_VAR => readVar(in,bc) + case TAG_VAR => (readVar(in,bc),bc) case x if ((x|TAG_PRIMITIVE)!=0) => (readPrimitive(x,in), bc) case _ => throw new IllegalStateException("Invalid term tag:"+tag) } @@ -170,14 +170,50 @@ trait Serializer extends TermSerializer case None => -1 } out.writeInt(scopeIndex) + writeName(t.name, out) + out.writeInt(t.index) bc } - private def readVar(in: Input, bc: BlockContext): (VarTerm, BlockContext) = ??? + private def readVar(in: Input, bc: BlockContext): VarTerm = + { + val scopeIndex = in.readInt + // TODO: handle error when scopeIndex is invalid ? + val scope: Option[Term] = if (scopeIndex == -1) None else bc.scopes.get(scopeIndex) + val name = readName(in) + val index = in.readInt() + VarTerm(name,index,scope,Map(),termSystem) + } - private def writeName(name:Name, out: Output): Unit = ??? + private def writeName(name:Name, out: Output): Unit = + { + out.writeInt(name.typeIndex) + name match { + case AtomName(v) => out << v + case StringName(v) => out << v + case CharName(v) => out << v + case LongName(v) => out << v + case IntName(v) => out << v + case DoubleName(v) => out << v + case OpaqueName(v) => out << v + } + } - private def readName(in: Input): Name = ??? + + private def readName(in: Input): Name = + { + import NameTypeIndexes._ + val typeIndex = in.readInt + typeIndex match { + case ATOM => AtomName(in.readString) + case STRING => StringName(in.readString) + case CHAR => CharName(in.readChar) + case LONG => LongName(in.readLong) + case INT => IntName(in.readInt) + case DOUBLE => DoubleName(in.readDouble) + case OPAQUE => OpaqueName(in.readOpaque) + } + } private def writeAttributes(attributes: Map[Name,Term], bc: BlockContext, out: Output): BlockContext = { diff --git a/src/main/scala/termware/util/Output.scala b/src/main/scala/termware/util/Output.scala index 319279c..f5ca0b4 100644 --- a/src/main/scala/termware/util/Output.scala +++ b/src/main/scala/termware/util/Output.scala @@ -47,6 +47,12 @@ trait Output def <<(v:Double): this.type = writeDouble(v) + def <<(v:Array[Byte]): this.type = { + writeInt(v.length) + write(v) + this + } + } From 1a70cbfa4247393b38c937da24151f3ac6a5cfdd Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Mon, 28 Dec 2015 15:01:15 +0200 Subject: [PATCH 20/27] implemented term serialization --- .../scala/termware/FreeTermStructure.scala | 16 ----- src/main/scala/termware/Term.scala | 2 +- src/main/scala/termware/TermStructure.scala | 72 ++++++++++++++++++- src/main/scala/termware/free/Serializer.scala | 37 +++++++--- 4 files changed, 100 insertions(+), 27 deletions(-) delete mode 100644 src/main/scala/termware/FreeTermStructure.scala diff --git a/src/main/scala/termware/FreeTermStructure.scala b/src/main/scala/termware/FreeTermStructure.scala deleted file mode 100644 index 87f879b..0000000 --- a/src/main/scala/termware/FreeTermStructure.scala +++ /dev/null @@ -1,16 +0,0 @@ -package termware - -case class FreeTermStructure(override val name:Name) extends TermStructure -{ - - override def componentIndex(name: Name): Option[Int] = - name match { - case IntName(i) => Some(i) - case _ => None - } - - override def componentName(i: Int): Option[Name] = - Some(IntName(i)) - -} - diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 61aa8ea..5f9afa1 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -82,7 +82,7 @@ case class StructuredTerm( object StructuredTerm { def apply(n:Name, components: IndexedSeq[Term]): StructuredTerm = - StructuredTerm(FreeTermStructure(n),components) + StructuredTerm(SeqTermStructure(n),components) } case class VarTerm(val name: Name, diff --git a/src/main/scala/termware/TermStructure.scala b/src/main/scala/termware/TermStructure.scala index be2d5b1..05734c0 100644 --- a/src/main/scala/termware/TermStructure.scala +++ b/src/main/scala/termware/TermStructure.scala @@ -1,12 +1,18 @@ package termware -trait TermStructure +import util._ + +/** + * Simple description: what are name of term and names of components. + **/ +sealed trait TermStructure { def name: Name def componentIndex(name:Name): Option[Int] def componentName(i: Int): Option[Name] + } case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) extends TermStructure @@ -22,3 +28,67 @@ case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) ext } else None } + +object DefaultTermStructure +{ + val typeIndex = 1 +} + +case class SeqTermStructure(name:Name) extends TermStructure +{ + + override def componentIndex(name:Name): Option[Int] = + name match { + case IntName(v) => Some(v) + case _ => None + } + + override def componentName(i:Int): Option[Name] = Some(IntName(i)) + +} + +object SeqTermStructure +{ + val typeIndex = 2 +} + +object TermStructure +{ + + def write(ts: TermStructure, out:Output): Unit = + ts match { + case DefaultTermStructure(name,components) => + out.writeInt(DefaultTermStructure.typeIndex) + free.Serializer.writeName(ts.name,out) + val nComponents = components.size + out.writeInt(nComponents) + for(i <- 1 to nComponents) { + val component = components(i) + free.Serializer.writeName(component,out) + } + case SeqTermStructure(name:Name) => + out.writeInt(SeqTermStructure.typeIndex) + free.Serializer.writeName(ts.name,out) + } + + def read(in: Input): TermStructure = + { + val typeIndex = in.readInt + typeIndex match { + case DefaultTermStructure.typeIndex => + val name = free.Serializer.readName(in) + val arity = in.readInt + val s0 = IndexedSeq[Name]() + val componentNames = (1 to arity).foldLeft(s0){ (s,i)=> + s :+ free.Serializer.readName(in) + } + DefaultTermStructure(name,componentNames) + case SeqTermStructure.typeIndex => + val name = free.Serializer.readName(in) + SeqTermStructure(name) + case _ => + throw new IllegalStateException("Unknown term-structure type index: typeIndex"); + } + } + +} diff --git a/src/main/scala/termware/free/Serializer.scala b/src/main/scala/termware/free/Serializer.scala index 1d2bdef..db604b2 100644 --- a/src/main/scala/termware/free/Serializer.scala +++ b/src/main/scala/termware/free/Serializer.scala @@ -10,9 +10,11 @@ import termware.TermAttributes.{empty=>emptyAttributes} trait Serializer extends TermSerializer { - def apply(t: Term, out: Output): Unit = ??? + def apply(t: Term, out: Output): Unit = + { writeTerm(t,BlockContext(),out) } - def unapply(input: Input): Term = ??? + def unapply(in: Input): Term = + readTerm(in,BlockContext())._1 def termSystem: TermSystem @@ -37,6 +39,7 @@ trait Serializer extends TermSerializer } } + def withScope(scope: Term): BlockContext = { invScopes.get(scope) match { @@ -84,7 +87,7 @@ trait Serializer extends TermSerializer val (t,nbc0) = tag match { case TAG_ATOM => (AtomTerm(in.readString,Map(),termSystem),bc) case TAG_STRUCTURED => readStructured(in, bc) - case TAG_TERMSTRUCTURE => readTerm(in,readTermStructure(in,bc)) + case TAG_TERMSTRUCTURE => readTerm(in,readAndAdoptTermStructure(in,bc)) case TAG_VAR => (readVar(in,bc),bc) case x if ((x|TAG_PRIMITIVE)!=0) => (readPrimitive(x,in), bc) case _ => throw new IllegalStateException("Invalid term tag:"+tag) @@ -131,7 +134,7 @@ trait Serializer extends TermSerializer val newTs = bc.structures.updated(newTsi,ts) val newInvTs = bc.invStructures.updated(ts, newTsi) out.writeInt(TAG_TERMSTRUCTURE) - writeStructure(ts,bc,out) + writeTermStructure(ts,out) bc.copy(structures=newTs, invStructures=newInvTs, structureIndex=newTsi) } val newScopeIndex = bc.scopeIndex+1 @@ -185,7 +188,7 @@ trait Serializer extends TermSerializer VarTerm(name,index,scope,Map(),termSystem) } - private def writeName(name:Name, out: Output): Unit = + def writeName(name:Name, out: Output): Unit = { out.writeInt(name.typeIndex) name match { @@ -200,7 +203,7 @@ trait Serializer extends TermSerializer } - private def readName(in: Input): Name = + def readName(in: Input): Name = { import NameTypeIndexes._ val typeIndex = in.readInt @@ -224,12 +227,28 @@ trait Serializer extends TermSerializer } } - private def readAttributes(in: Input, bc: BlockContext): (Map[Name,Term], BlockContext) = ??? + private def readAttributes(in: Input, bc: BlockContext): (Map[Name,Term], BlockContext) = + { + val r: Map[Name,Term] = Map() + val nAttributes = in.readInt + (1 to nAttributes).foldLeft((r,bc)) { (s,i) => + val name = readName(in) + val (t,nbc) = readTerm(in,s._2) + (s._1.updated(name,t),nbc) + } + } - private def writeStructure(ts: TermStructure, bc: BlockContext, out: Output): BlockContext = ??? + private def writeTermStructure(ts: TermStructure, out: Output): Unit = + TermStructure.write(ts,out) - private def readTermStructure(in: Input, bc: BlockContext): BlockContext = ??? + private def readTermStructure(in: Input): TermStructure = + TermStructure.read(in) + private def readAndAdoptTermStructure(in: Input, bc: BlockContext): BlockContext = + { + val ts = TermStructure.read(in) + bc withStructure ts + } } From d3d93dd1cbc6f197b90b4723707c30df6ae5e77e Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Thu, 31 Dec 2015 01:44:05 +0200 Subject: [PATCH 21/27] work with scopeIndex-es intead sxcopes. --- src/main/scala/termware/AtomTermOps.scala | 6 +- src/main/scala/termware/Match.scala | 12 +-- .../scala/termware/PrimitiveTermOps.scala | 6 +- .../scala/termware/StructuredTermOps.scala | 6 +- src/main/scala/termware/Term.scala | 13 +-- src/main/scala/termware/TermBuilder.scala | 40 +++++++++ src/main/scala/termware/TermContext.scala | 14 ++++ .../scala/termware/TermEmptyComponents.scala | 2 + src/main/scala/termware/TermOps.scala | 6 +- src/main/scala/termware/TermStructure.scala | 27 ++++-- src/main/scala/termware/TermWithContext.scala | 22 +++++ src/main/scala/termware/Unification.scala | 2 +- src/main/scala/termware/VarTermOps.scala | 2 +- src/main/scala/termware/free/Serializer.scala | 84 +++++++++---------- .../scala/termware/free/Unification.scala | 58 ++++++------- src/main/scala/termware/util/Output.scala | 4 + 16 files changed, 206 insertions(+), 98 deletions(-) create mode 100644 src/main/scala/termware/TermBuilder.scala create mode 100644 src/main/scala/termware/TermContext.scala create mode 100644 src/main/scala/termware/TermWithContext.scala diff --git a/src/main/scala/termware/AtomTermOps.scala b/src/main/scala/termware/AtomTermOps.scala index c485aaf..99c716b 100644 --- a/src/main/scala/termware/AtomTermOps.scala +++ b/src/main/scala/termware/AtomTermOps.scala @@ -8,10 +8,14 @@ trait AtomTermOps extends TermEmptyComponents override def isScoped = true - override def scope = None + override def isScope = false + + override def scopeIndex = -1 override def isVar = false + override def varIndex = -1 + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } diff --git a/src/main/scala/termware/Match.scala b/src/main/scala/termware/Match.scala index 1ca3402..f511f38 100644 --- a/src/main/scala/termware/Match.scala +++ b/src/main/scala/termware/Match.scala @@ -2,16 +2,16 @@ package termware sealed trait Match { - def put(x:Term,y:Term, u: Unification, s: Term): Match - + def put(x:TermWithContext ,y:TermWithContext, u: Unification, s: Term): Match // ts ? def merge(x: Match, u: Unification, s:Term): Match } -case class Substitution(mapping: Map[Term,Term]) extends Match + +case class Substitution(mapping: Map[TermWithContext,TermWithContext]) extends Match { - def put(x:Term, y:Term, u: Unification, s: Term): Match = + def put(x:TermWithContext, y:TermWithContext, u: Unification, s: Term): Match = { def updated = Substitution(mapping.updated(x,y)) mapping.get(x) match { @@ -33,10 +33,10 @@ case class Substitution(mapping: Map[Term,Term]) extends Match } -case class MatchFailure(val x: Term, val y: Term, val reason: String) extends Match +case class MatchFailure(val x: TermWithContext, val y: TermWithContext, val reason: String) extends Match { - def put(x:Term,y:Term, u: Unification, s: Term): Match = this + def put(x:TermWithContext,y:TermWithContext, u: Unification, s: Term): Match = this def merge(x: Match, u: Unification, s:Term ): Match = this diff --git a/src/main/scala/termware/PrimitiveTermOps.scala b/src/main/scala/termware/PrimitiveTermOps.scala index a9f4de5..5e58a17 100644 --- a/src/main/scala/termware/PrimitiveTermOps.scala +++ b/src/main/scala/termware/PrimitiveTermOps.scala @@ -17,9 +17,13 @@ trait PrimitiveTermOps override def isVar = false + override def varIndex = -1 + override def isScoped = false - override def scope = None + override def isScope = false + + override def scopeIndex = -1 } diff --git a/src/main/scala/termware/StructuredTermOps.scala b/src/main/scala/termware/StructuredTermOps.scala index c1f4e3f..14f2d63 100644 --- a/src/main/scala/termware/StructuredTermOps.scala +++ b/src/main/scala/termware/StructuredTermOps.scala @@ -22,10 +22,14 @@ trait StructuredTermOps extends TermOps override def isVar: Boolean = false - override def scope = None + override def varIndex = -1 + + override def scopeIndex = -1 override def isScoped = false + override def isScope = termStructure.isScope + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 5f9afa1..5511d12 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -5,17 +5,18 @@ sealed trait Term extends TermOps { val attributes: Map[Name,Term] = Map() val termSystem: TermSystem = FreeTermSystem - } case class AtomTerm(value:String, - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map(), + override val termSystem: TermSystem = FreeTermSystem ) extends Term with AtomTermOps { override val name = AtomName(value) } + + sealed trait PrimitiveTerm extends Term with PrimitiveTermOps @@ -82,12 +83,12 @@ case class StructuredTerm( object StructuredTerm { def apply(n:Name, components: IndexedSeq[Term]): StructuredTerm = - StructuredTerm(SeqTermStructure(n),components) + StructuredTerm(SeqTermStructure(n,false),components) } case class VarTerm(val name: Name, - val index: Int, - override val scope: Option[Term] = None, + val varIndex: Int, // index in scope. + override val scopeIndex: Int = -1, // index of scope. point to override val attributes: Map[Name,Term] = Map(), override val termSystem: TermSystem = FreeTermSystem ) extends Term with VarTermOps diff --git a/src/main/scala/termware/TermBuilder.scala b/src/main/scala/termware/TermBuilder.scala new file mode 100644 index 0000000..738bef4 --- /dev/null +++ b/src/main/scala/termware/TermBuilder.scala @@ -0,0 +1,40 @@ +package termware + +// TODO: make one mutable. +case class TermBuilder( + private val parent: Option[TermBuilder], + private val structure: TermStructure, + private val components: IndexedSeq[Term]=IndexedSeq(), + private val scopeIndex: Int, + private val lastScopeIndex: Int, + private val nVariables: Int, + private val termSystem: TermSystem + ) +{ + + + def startChild(ts: TermStructure) : TermBuilder = + { + val (newScopeIndex, newLastScopeIndex) = if (ts.isScope) { + val newScopeIndex = lastScopeIndex+1 + (newScopeIndex, newScopeIndex) + } else (-1, lastScopeIndex) + new TermBuilder(Some(this),ts,IndexedSeq(), newScopeIndex, newLastScopeIndex, 0, termSystem) + } + + def finishChild(): TermBuilder = + { + parent.get.addTermWithScope(StructuredTerm(structure,components,Map(),termSystem),lastScopeIndex) + } + + def addTermWithScope(t: Term, newLastScopeIndex: Int): TermBuilder = + copy(components = components :+ t, lastScopeIndex = lastScopeIndex) + + def addPrimitive(t: PrimitiveTerm): TermBuilder = + copy(components = components :+ t) + + def addAtom(t: AtomTerm): TermBuilder = + copy(components = components :+ t) + + +} diff --git a/src/main/scala/termware/TermContext.scala b/src/main/scala/termware/TermContext.scala new file mode 100644 index 0000000..64adc26 --- /dev/null +++ b/src/main/scala/termware/TermContext.scala @@ -0,0 +1,14 @@ +package termware + +trait TermContext +{ + + def scope(index:Int):Term + + // def variable(scopeIndex:Int, varIndex:Int):VarTerm + + // def resolve(name:Name):Option[VarTerm] + + def childContext(term: Term, parent: TermWithContext): TermContext + +} diff --git a/src/main/scala/termware/TermEmptyComponents.scala b/src/main/scala/termware/TermEmptyComponents.scala index bdd2fcd..085f715 100644 --- a/src/main/scala/termware/TermEmptyComponents.scala +++ b/src/main/scala/termware/TermEmptyComponents.scala @@ -16,5 +16,7 @@ trait TermEmptyComponents override def componentIndex(n:Name) = None + override def isScope = true + } diff --git a/src/main/scala/termware/TermOps.scala b/src/main/scala/termware/TermOps.scala index 7f67aad..c6e4209 100644 --- a/src/main/scala/termware/TermOps.scala +++ b/src/main/scala/termware/TermOps.scala @@ -16,12 +16,16 @@ trait TermOps def component(n: Name): Option[Term] + def isScope: Boolean + def isScoped: Boolean - def scope: Option[Term] + def scopeIndex: Int def isVar: Boolean + def varIndex: Int + def withAttributes(attributes: Map[Name,Term]): Term } diff --git a/src/main/scala/termware/TermStructure.scala b/src/main/scala/termware/TermStructure.scala index 05734c0..36d0335 100644 --- a/src/main/scala/termware/TermStructure.scala +++ b/src/main/scala/termware/TermStructure.scala @@ -7,15 +7,22 @@ import util._ **/ sealed trait TermStructure { + + def name: Name def componentIndex(name:Name): Option[Int] def componentName(i: Int): Option[Name] + /** + * is this term define a scope ? + */ + def isScope: Boolean + } -case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) extends TermStructure +case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name], isScope: Boolean) extends TermStructure { val componentIndexes = componentNames.foldLeft(Map[Name,Int]()){ (s,e) => s.updated(e,s.size+1) } @@ -34,7 +41,7 @@ object DefaultTermStructure val typeIndex = 1 } -case class SeqTermStructure(name:Name) extends TermStructure +case class SeqTermStructure(name:Name, isScope: Boolean) extends TermStructure { override def componentIndex(name:Name): Option[Int] = @@ -56,9 +63,11 @@ object TermStructure { def write(ts: TermStructure, out:Output): Unit = + { ts match { - case DefaultTermStructure(name,components) => + case DefaultTermStructure(name,components,isScope) => out.writeInt(DefaultTermStructure.typeIndex) + out.writeBoolean(isScope) free.Serializer.writeName(ts.name,out) val nComponents = components.size out.writeInt(nComponents) @@ -66,26 +75,28 @@ object TermStructure val component = components(i) free.Serializer.writeName(component,out) } - case SeqTermStructure(name:Name) => + case SeqTermStructure(name,isScope) => out.writeInt(SeqTermStructure.typeIndex) + out.writeBoolean(isScope) free.Serializer.writeName(ts.name,out) } + } def read(in: Input): TermStructure = { val typeIndex = in.readInt + val isScope = (in.readByte != 0) + val name = free.Serializer.readName(in) typeIndex match { case DefaultTermStructure.typeIndex => - val name = free.Serializer.readName(in) val arity = in.readInt val s0 = IndexedSeq[Name]() val componentNames = (1 to arity).foldLeft(s0){ (s,i)=> s :+ free.Serializer.readName(in) } - DefaultTermStructure(name,componentNames) + DefaultTermStructure(name,componentNames,isScope) case SeqTermStructure.typeIndex => - val name = free.Serializer.readName(in) - SeqTermStructure(name) + SeqTermStructure(name, isScope) case _ => throw new IllegalStateException("Unknown term-structure type index: typeIndex"); } diff --git a/src/main/scala/termware/TermWithContext.scala b/src/main/scala/termware/TermWithContext.scala new file mode 100644 index 0000000..c20ab3d --- /dev/null +++ b/src/main/scala/termware/TermWithContext.scala @@ -0,0 +1,22 @@ +package termware + +case class TermWithContext(term: Term, context: TermContext) +{ + + def scope(): Option[Term] = + if (term.scopeIndex == -1) None else Some(context.scope(term.scopeIndex)) + + def arity(): Int = term.arity + + def components(): IndexedSeq[TermWithContext] = + { + term match { + case st: StructuredTerm => + st.components map (x => TermWithContext(x, context.childContext(x,this) )) + case _ => IndexedSeq() + } + } + +} + + diff --git a/src/main/scala/termware/Unification.scala b/src/main/scala/termware/Unification.scala index 6a764f9..74a531c 100644 --- a/src/main/scala/termware/Unification.scala +++ b/src/main/scala/termware/Unification.scala @@ -3,6 +3,6 @@ package termware trait Unification { - def apply(x: Term, y: Term, scope:Term): Match + def apply(x: TermWithContext, y: TermWithContext, scope:Term): Match } diff --git a/src/main/scala/termware/VarTermOps.scala b/src/main/scala/termware/VarTermOps.scala index 4b39a4a..1f0b38d 100644 --- a/src/main/scala/termware/VarTermOps.scala +++ b/src/main/scala/termware/VarTermOps.scala @@ -6,7 +6,7 @@ trait VarTermOps extends TermEmptyComponents override def isVar = true - override def isScoped = scope.isDefined + override def isScoped = scopeIndex != -1 override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) diff --git a/src/main/scala/termware/free/Serializer.scala b/src/main/scala/termware/free/Serializer.scala index db604b2..99d8940 100644 --- a/src/main/scala/termware/free/Serializer.scala +++ b/src/main/scala/termware/free/Serializer.scala @@ -22,33 +22,37 @@ trait Serializer extends TermSerializer case class BlockContext( val structures: Map[Int, TermStructure] = Map(), val invStructures: Map[TermStructure, Int] = Map(), - val structureIndex: Int = 0, + val nextStructureIndex: Int = 0, val scopes: Map[Int, Term] = Map(), val invScopes: Map[Term,Int] = Map(), - val scopeIndex: Int = 0 + val nextScopeIndex: Int = 0 ) { - def withStructure(structure: TermStructure): BlockContext = + def withStructure(structure: TermStructure): (BlockContext, Int) = { invStructures.get(structure) match { - case None => val si = structureIndex+1 - copy(structures = structures.updated(si, structure), - invStructures = invStructures.updated(structure,si), - structureIndex = si) - case Some(si) => this + case None => val si = nextStructureIndex + val nsi = si+1 + (copy(structures = structures.updated(si, structure), + invStructures = invStructures.updated(structure,si), + nextStructureIndex = nsi), nsi) + case Some(si) => (this, si) } } + def retrieveStructure(i: Int): TermStructure = + structures.get(i).getOrElse(throw new IllegalStateException("Invalid structure index")) - def withScope(scope: Term): BlockContext = + def withScope(scope: Term): (BlockContext, Int) = { invScopes.get(scope) match { case None => - val si = scopeIndex+1 - copy(scopes = scopes.updated(si,scope), - invScopes = invScopes.updated(scope,si), - scopeIndex = si) - case Some(_) => this + val si = nextScopeIndex + val nsi = si+1 + (copy(scopes = scopes.updated(si,scope), + invScopes = invScopes.updated(scope,si), + nextScopeIndex = nsi), nsi) + case Some(si) => (this, si) } } @@ -127,22 +131,19 @@ trait Serializer extends TermSerializer private def writeStructured(t: StructuredTerm, bc: BlockContext, out: Output): BlockContext = { val ts = t.termStructure; - val nbc0 = bc.invStructures.get(ts) match { - case Some(tsi) => bc - case None => - val newTsi = bc.structureIndex+1 - val newTs = bc.structures.updated(newTsi,ts) - val newInvTs = bc.invStructures.updated(ts, newTsi) - out.writeInt(TAG_TERMSTRUCTURE) - writeTermStructure(ts,out) - bc.copy(structures=newTs, invStructures=newInvTs, structureIndex=newTsi) + val nextSti = bc.nextStructureIndex + val (nbc0, sti) = bc.withStructure(ts) + if (nextSti == sti) { + out.writeInt(TAG_TERMSTRUCTURE) + out.writeInt(sti) + writeTermStructure(ts,out) } - val newScopeIndex = bc.scopeIndex+1 - val newScopes = bc.scopes.updated(newScopeIndex,t) - val newInvScopes = bc.invScopes.updated(t,newScopeIndex) - val nbc = nbc0.copy(scopes=newScopes, invScopes=newInvScopes, scopeIndex=newScopeIndex) + val (nbc, sci) = if (t.isScope) { + nbc0 withScope t + } else (nbc0, -1) out.writeInt(TAG_STRUCTURED) - out.writeInt(nbc.structureIndex) + out.writeInt(sti) + out.writeInt(sci) out.writeInt(t.arity) t.components.foldLeft(nbc) { (s,e) => writeTerm(e,s,out) @@ -151,9 +152,11 @@ trait Serializer extends TermSerializer private def readStructured(in: Input, bc: BlockContext): (Term, BlockContext) = { - val tsi = in.readInt - val ts: TermStructure = bc.structures.getOrElse(tsi,throw new IllegalStateException( - "invalid structure index ")) + val ts = bc.retrieveStructure(in.readInt) + val sci = in.readInt + if (sci != -1) { + ??? + } val arity = in.readInt val subterms = new Array[Term](arity) var cbc = bc @@ -167,25 +170,18 @@ trait Serializer extends TermSerializer private def writeVar(t: VarTerm, bc: BlockContext, out: Output): BlockContext = { - val scopeIndex = t.scope match { - case Some(u) => bc.invScopes.getOrElse(u, - throw new IllegalStateException("scope not found in uplevel")) - case None => -1 - } - out.writeInt(scopeIndex) writeName(t.name, out) - out.writeInt(t.index) + out.writeInt(t.varIndex) + out.writeInt(t.scopeIndex) bc } private def readVar(in: Input, bc: BlockContext): VarTerm = { - val scopeIndex = in.readInt - // TODO: handle error when scopeIndex is invalid ? - val scope: Option[Term] = if (scopeIndex == -1) None else bc.scopes.get(scopeIndex) val name = readName(in) - val index = in.readInt() - VarTerm(name,index,scope,Map(),termSystem) + val varIndex = in.readInt() + val scopeIndex = in.readInt + VarTerm(name=name,varIndex,scopeIndex,Map(),termSystem) } def writeName(name:Name, out: Output): Unit = @@ -247,7 +243,7 @@ trait Serializer extends TermSerializer private def readAndAdoptTermStructure(in: Input, bc: BlockContext): BlockContext = { val ts = TermStructure.read(in) - bc withStructure ts + (bc withStructure ts)._1 } } diff --git a/src/main/scala/termware/free/Unification.scala b/src/main/scala/termware/free/Unification.scala index bc75cb7..09e9ba1 100644 --- a/src/main/scala/termware/free/Unification.scala +++ b/src/main/scala/termware/free/Unification.scala @@ -7,11 +7,11 @@ object Unification extends termware.Unification // naive recursive implementation. // TODO: rewrite - def apply(x: Term, y: Term, scope: Term): Match = + def apply(x: TermWithContext, y: TermWithContext, scope: Term): Match = { - x match { + x.term match { case AtomTerm(xv,xa,xts) => - y match { + y.term match { case AtomTerm(yv,ya,yts) => if (xv == yv) { Substitution.empty @@ -19,7 +19,7 @@ object Unification extends termware.Unification MatchFailure(x,y,"different atoms") } case VarTerm(yn,yi,ys,xa,ts) => - if (ys.forall(_ eq scope)) { + if (y.scope.forall(_ eq scope)) { Substitution(Map(y->x)) } else { MatchFailure(x,y,"can't unify atom and non-with var") @@ -28,10 +28,10 @@ object Unification extends termware.Unification MatchFailure(x,y,"can't unify atom with non-atom") } case px:PrimitiveTerm => - y match { - case py:PrimitiveTerm => applyPrimitive(px,py) + y.term match { + case py:PrimitiveTerm => applyPrimitive(px,py,x,y) case VarTerm(yn,yi,ys,xa,ts) => - if (ys.forall(_ eq scope)) { + if (y.scope.forall(_ eq scope)) { Substitution(Map(y->x)) } else { MatchFailure(x,y,"can't unify primitive and non-with var") @@ -40,7 +40,7 @@ object Unification extends termware.Unification MatchFailure(x,y,"can't unify primitive with non-primitive") } case StructuredTerm(xstructure,xcomponents,xa,xts) => - y match { + y.term match { case StructuredTerm(ystructure,ycomponents,ya,yts) => if (ystructure.name != ystructure.name) { MatchFailure(x,y,"name mismatch") @@ -48,11 +48,12 @@ object Unification extends termware.Unification MatchFailure(x,y,"arity mismatch") } else { var s0: Match = Substitution.empty - (xcomponents zip ycomponents).foldLeft(s0){ (s,e) => - s.merge(apply(e._1,e._2,scope),this,scope) } + // TODO: define components as term-with-context. + (x.components zip y.components).foldLeft(s0){ (s,e) => + s.merge(apply(e._1,e._2,scope),this,scope) } } case VarTerm(yn,yi,ys,xa,ts) => - if (ys.forall(_ eq scope)) { + if (y.scope.forall(_ eq scope)) { Substitution(Map(y->x)) } else { MatchFailure(x,y,"can't unify structured term and non-with var") @@ -61,14 +62,15 @@ object Unification extends termware.Unification MatchFailure(x,y,"structure mismatch") } case VarTerm(xn,xi,xs,xa,ts) => - if (xs.forall(_ eq scope)) { + if (x.scope.forall(_ eq scope)) { Substitution(Map(x->y)) } else { - y match { + y.term match { case VarTerm(yn,yi,ys,xa,ts) => - if (ys.forall(_ eq scope)) { + if (y.scope.forall(_ eq scope)) { Substitution(Map(y->x)) - } else if (ys.get eq xs.get) { + } else if ( (y.scope.get eq x.scope.get) && xi == yi) { + // TODO: review. Substitution.empty } else { MatchFailure(x,y,"var mismatch") @@ -80,55 +82,55 @@ object Unification extends termware.Unification } } - def applyPrimitive(x: PrimitiveTerm, y: PrimitiveTerm): Match = + def applyPrimitive(x: PrimitiveTerm, y: PrimitiveTerm, xc: TermWithContext, yc: TermWithContext): Match = x match { case StringTerm(xv,xa,xts) => y match { case StringTerm(yv,ya,yts) => if (xv == yv) Substitution.empty - else MatchFailure(x,y,"string mismatch") + else MatchFailure(xc,yc,"string mismatch") case _ => - MatchFailure(x,y,"type mismatch") + MatchFailure(xc,yc,"type mismatch") } case CharTerm(xv,xa,xts) => y match { case CharTerm(yv,ya,yts) => if (xv == yv) Substitution.empty - else MatchFailure(x,y,"char mismatch") + else MatchFailure(xc,yc,"char mismatch") case _ => - MatchFailure(x,y,"type mismatch") + MatchFailure(xc,yc,"type mismatch") } case Int32Term(xv,xa,xts) => y match { case Int32Term(yv,ya,yts) => if (xv == yv) Substitution.empty - else MatchFailure(x,y,"int32 mismatch") + else MatchFailure(xc,yc,"int32 mismatch") case _ => - MatchFailure(x,y,"type mismatch") + MatchFailure(xc,yc,"type mismatch") } case Int64Term(xv,xa,xts) => y match { case Int64Term(yv,ya,yts) => if (xv == yv) Substitution.empty - else MatchFailure(x,y,"int64 mismatch") + else MatchFailure(xc,yc,"int64 mismatch") case _ => - MatchFailure(x,y,"type mismatch") + MatchFailure(xc,yc,"type mismatch") } case DoubleTerm(xv,xa,xts) => y match { case DoubleTerm(yv,ya,yts) => if (xv == yv) Substitution.empty - else MatchFailure(x,y,"double mismatch") + else MatchFailure(xc,yc,"double mismatch") case _ => - MatchFailure(x,y,"type mismatch") + MatchFailure(xc,yc,"type mismatch") } case OpaqueTerm(xv,xa,xts) => y match { case OpaqueTerm(yv,ya,yts) => if (xv == yv) Substitution.empty - else MatchFailure(x,y,"double mismatch") + else MatchFailure(xc,yc,"double mismatch") case _ => - MatchFailure(x,y,"type mismatch") + MatchFailure(xc,yc,"type mismatch") } } diff --git a/src/main/scala/termware/util/Output.scala b/src/main/scala/termware/util/Output.scala index f5ca0b4..72c5194 100644 --- a/src/main/scala/termware/util/Output.scala +++ b/src/main/scala/termware/util/Output.scala @@ -10,6 +10,10 @@ trait Output def write(value: Byte): Unit + def writeByte(value: Byte): Unit = write(value) + + def writeBoolean(value: Boolean): Unit = + writeByte( if (value) 1 else 0 ) def writeChar(v:Char): this.type = writeInt(v.toInt) From 42761b232811a920dcb368c6d1ac195e32ba193f Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Thu, 31 Dec 2015 10:22:37 +0200 Subject: [PATCH 22/27] fixed test-compile --- src/main/scala/termware/TermWithContext.scala | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/scala/termware/TermWithContext.scala b/src/main/scala/termware/TermWithContext.scala index c20ab3d..ef3f311 100644 --- a/src/main/scala/termware/TermWithContext.scala +++ b/src/main/scala/termware/TermWithContext.scala @@ -6,17 +6,30 @@ case class TermWithContext(term: Term, context: TermContext) def scope(): Option[Term] = if (term.scopeIndex == -1) None else Some(context.scope(term.scopeIndex)) - def arity(): Int = term.arity + + def name: Name = term.name + + def arity: Int = term.arity def components(): IndexedSeq[TermWithContext] = { term match { case st: StructuredTerm => - st.components map (x => TermWithContext(x, context.childContext(x,this) )) + st.components map wrapChild case _ => IndexedSeq() } } + def component(n:Name): Option[TermWithContext] = + term.component(n) map wrapChild + + def component(i:Int): Option[TermWithContext] = + term.component(i) map wrapChild + + + private def wrapChild(c: Term): TermWithContext = + TermWithContext(c, context.childContext(c,this)) + } From 996262c1317f3b8e33bd15b5c2630e0b6b36117c Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Thu, 31 Dec 2015 15:45:35 +0200 Subject: [PATCH 23/27] implemented FreeTermContext --- src/main/scala/termware/FreeTermSystem.scala | 2 +- .../scala/termware/ProcessingException.scala | 9 ++++ src/main/scala/termware/Term.scala | 28 ++++--------- src/main/scala/termware/TermBuilder.scala | 7 ++-- src/main/scala/termware/TermContext.scala | 4 +- src/main/scala/termware/TermSystem.scala | 7 +++- src/main/scala/termware/TermWithContext.scala | 3 +- .../scala/termware/free/FreeTermContext.scala | 37 ++++++++++++++++ src/main/scala/termware/free/Serializer.scala | 39 +++++++---------- .../scala/termware/free/Unification.scala | 42 +++++++++---------- src/main/scala/termware/package.scala | 7 ++++ 11 files changed, 112 insertions(+), 73 deletions(-) create mode 100644 src/main/scala/termware/ProcessingException.scala create mode 100644 src/main/scala/termware/free/FreeTermContext.scala create mode 100644 src/main/scala/termware/package.scala diff --git a/src/main/scala/termware/FreeTermSystem.scala b/src/main/scala/termware/FreeTermSystem.scala index b05b880..0b56247 100644 --- a/src/main/scala/termware/FreeTermSystem.scala +++ b/src/main/scala/termware/FreeTermSystem.scala @@ -6,7 +6,7 @@ object FreeTermSystem extends TermSystem def name: Term = new AtomTerm("Free") - override def adopt(t: Term): Term = t + override def adopt(t: Term): TermWithContext = ??? override def unification: Unification = free.Unification diff --git a/src/main/scala/termware/ProcessingException.scala b/src/main/scala/termware/ProcessingException.scala new file mode 100644 index 0000000..d12e5fc --- /dev/null +++ b/src/main/scala/termware/ProcessingException.scala @@ -0,0 +1,9 @@ +package termware + + +class ProcessingException(s:String,e:Throwable) extends RuntimeException(s,e) +{ + + def this(s:String) = this(s, null) + +} diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 5511d12..5d38a8b 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -4,12 +4,10 @@ package termware sealed trait Term extends TermOps { val attributes: Map[Name,Term] = Map() - val termSystem: TermSystem = FreeTermSystem } case class AtomTerm(value:String, - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map() ) extends Term with AtomTermOps { override val name = AtomName(value) @@ -21,16 +19,14 @@ sealed trait PrimitiveTerm extends Term with PrimitiveTermOps case class StringTerm(value:String, - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map() ) extends PrimitiveTerm with StringTermOps { override val name = StringName(value) } case class CharTerm(value:Character, - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map() ) extends PrimitiveTerm with CharTermOps { override val name = CharName(value) @@ -39,32 +35,28 @@ case class CharTerm(value:Character, sealed trait NumericTerm extends PrimitiveTerm with NumericTermOps case class Int32Term(value:Int, - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map() ) extends NumericTerm with Int32TermOps { override val name = IntName(value) } case class Int64Term(value: Long, - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map() ) extends NumericTerm with Int64TermOps { override val name = LongName(value) } case class DoubleTerm(value: Double, - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map() ) extends NumericTerm with DoubleTermOps { override val name = DoubleName(value) } case class OpaqueTerm(value: Array[Byte], - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map() ) extends PrimitiveTerm with OpaqueTermOps { override val name = OpaqueName(value) @@ -74,8 +66,7 @@ case class OpaqueTerm(value: Array[Byte], case class StructuredTerm( termStructure: TermStructure, components: IndexedSeq[Term], - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map() ) extends Term with StructuredTermOps { } @@ -89,8 +80,7 @@ object StructuredTerm case class VarTerm(val name: Name, val varIndex: Int, // index in scope. override val scopeIndex: Int = -1, // index of scope. point to - override val attributes: Map[Name,Term] = Map(), - override val termSystem: TermSystem = FreeTermSystem + override val attributes: Map[Name,Term] = Map() ) extends Term with VarTermOps { } diff --git a/src/main/scala/termware/TermBuilder.scala b/src/main/scala/termware/TermBuilder.scala index 738bef4..72e6908 100644 --- a/src/main/scala/termware/TermBuilder.scala +++ b/src/main/scala/termware/TermBuilder.scala @@ -7,8 +7,7 @@ case class TermBuilder( private val components: IndexedSeq[Term]=IndexedSeq(), private val scopeIndex: Int, private val lastScopeIndex: Int, - private val nVariables: Int, - private val termSystem: TermSystem + private val nVariables: Int ) { @@ -19,12 +18,12 @@ case class TermBuilder( val newScopeIndex = lastScopeIndex+1 (newScopeIndex, newScopeIndex) } else (-1, lastScopeIndex) - new TermBuilder(Some(this),ts,IndexedSeq(), newScopeIndex, newLastScopeIndex, 0, termSystem) + new TermBuilder(Some(this),ts,IndexedSeq(), newScopeIndex, newLastScopeIndex, 0) } def finishChild(): TermBuilder = { - parent.get.addTermWithScope(StructuredTerm(structure,components,Map(),termSystem),lastScopeIndex) + parent.get.addTermWithScope(StructuredTerm(structure,components,Map()),lastScopeIndex) } def addTermWithScope(t: Term, newLastScopeIndex: Int): TermBuilder = diff --git a/src/main/scala/termware/TermContext.scala b/src/main/scala/termware/TermContext.scala index 64adc26..9e75077 100644 --- a/src/main/scala/termware/TermContext.scala +++ b/src/main/scala/termware/TermContext.scala @@ -3,7 +3,9 @@ package termware trait TermContext { - def scope(index:Int):Term + def scope(source: Term, index:Int):Term + + def termSystem(): TermSystem // def variable(scopeIndex:Int, varIndex:Int):VarTerm diff --git a/src/main/scala/termware/TermSystem.scala b/src/main/scala/termware/TermSystem.scala index 3d50dae..96eb44a 100644 --- a/src/main/scala/termware/TermSystem.scala +++ b/src/main/scala/termware/TermSystem.scala @@ -5,14 +5,17 @@ trait TermSystem { def name: Term - def adopt(t: Term): Term = t + def adopt(t: Term): TermWithContext = ??? def unification: Unification = free.Unification - def storage: TermStorage = ??? + def resolve(name: Term): Option[Term] = ??? // Todo: s/Option/ResolveResult + + def storage: TermStorage = ??? // baseTermStorage(name) def serializer: TermSerializer = free.Serializer def isFree: Boolean = false } + diff --git a/src/main/scala/termware/TermWithContext.scala b/src/main/scala/termware/TermWithContext.scala index ef3f311..262789a 100644 --- a/src/main/scala/termware/TermWithContext.scala +++ b/src/main/scala/termware/TermWithContext.scala @@ -4,8 +4,7 @@ case class TermWithContext(term: Term, context: TermContext) { def scope(): Option[Term] = - if (term.scopeIndex == -1) None else Some(context.scope(term.scopeIndex)) - + if (term.scopeIndex == -1) None else Some(context.scope(term,term.scopeIndex)) def name: Name = term.name diff --git a/src/main/scala/termware/free/FreeTermContext.scala b/src/main/scala/termware/free/FreeTermContext.scala new file mode 100644 index 0000000..b81d9bb --- /dev/null +++ b/src/main/scala/termware/free/FreeTermContext.scala @@ -0,0 +1,37 @@ +package termware.free + +import termware._ + +sealed trait FreeTermContext extends TermContext + +case class TopLevelTermContext(override val termSystem: TermSystem) extends FreeTermContext +{ + + def childContext(term: Term,parent: TermWithContext):TermContext = + ChildTermContext(termSystem, parent) + + def scope(source: Term, index: Int): Term = + if (source.isScope && source.scopeIndex == index) { + source + } else { + throwPE(s"scope ${index} is not not found") + } + +} + +case class ChildTermContext(override val termSystem: TermSystem, val parent: TermWithContext) extends FreeTermContext +{ + + def childContext(term: Term,parent: TermWithContext):TermContext = + ChildTermContext(termSystem, parent) + + def scope(source: Term, index: Int): Term = + if (source.isScope && source.scopeIndex == index) { + source + } else { + parent.context.scope(parent.term, index) + } + + +} + diff --git a/src/main/scala/termware/free/Serializer.scala b/src/main/scala/termware/free/Serializer.scala index 99d8940..0eabb3c 100644 --- a/src/main/scala/termware/free/Serializer.scala +++ b/src/main/scala/termware/free/Serializer.scala @@ -7,7 +7,7 @@ import termware.TermAttributes.{empty=>emptyAttributes} // TODO: write input pos on error. -trait Serializer extends TermSerializer +object Serializer extends TermSerializer { def apply(t: Term, out: Output): Unit = @@ -16,9 +16,6 @@ trait Serializer extends TermSerializer def unapply(in: Input): Term = readTerm(in,BlockContext())._1 - def termSystem: TermSystem - - case class BlockContext( val structures: Map[Int, TermStructure] = Map(), val invStructures: Map[TermStructure, Int] = Map(), @@ -89,7 +86,7 @@ trait Serializer extends TermSerializer { val tag = in.readInt val (t,nbc0) = tag match { - case TAG_ATOM => (AtomTerm(in.readString,Map(),termSystem),bc) + case TAG_ATOM => (AtomTerm(in.readString,Map()),bc) case TAG_STRUCTURED => readStructured(in, bc) case TAG_TERMSTRUCTURE => readTerm(in,readAndAdoptTermStructure(in,bc)) case TAG_VAR => (readVar(in,bc),bc) @@ -105,12 +102,12 @@ trait Serializer extends TermSerializer { out << (TAG_PRIMITIVE | p.name.typeIndex) p match { - case StringTerm(v,_,_) => out << v - case CharTerm(v,_,_) => out << v - case Int32Term(v,_,_) => out << v - case Int64Term(v,_,_) => out << v - case DoubleTerm(v,_,_) => out << v - case OpaqueTerm(v,_,_) => (out << v.size).write(v) + case StringTerm(v,_) => out << v + case CharTerm(v,_) => out << v + case Int32Term(v,_) => out << v + case Int64Term(v,_) => out << v + case DoubleTerm(v,_) => out << v + case OpaqueTerm(v,_) => (out << v.size).write(v) } } @@ -118,12 +115,12 @@ trait Serializer extends TermSerializer { import NameTypeIndexes._ (tag & (~TAG_PRIMITIVE)) match { - case STRING => StringTerm(in.readString,Map(),termSystem) - case CHAR => CharTerm(in.readChar,Map(),termSystem) - case INT => Int32Term(in.readInt,Map(),termSystem) - case LONG => Int64Term(in.readLong,Map(),termSystem) - case DOUBLE => DoubleTerm(in.readDouble(),Map(),termSystem) - case OPAQUE => OpaqueTerm(in.readOpaque(),Map(),termSystem) + case STRING => StringTerm(in.readString,Map()) + case CHAR => CharTerm(in.readChar,Map()) + case INT => Int32Term(in.readInt,Map()) + case LONG => Int64Term(in.readLong,Map()) + case DOUBLE => DoubleTerm(in.readDouble(),Map()) + case OPAQUE => OpaqueTerm(in.readOpaque(),Map()) case _ => throw new IllegalStateException("Invalid primitive tag: "+tag) } } @@ -165,7 +162,7 @@ trait Serializer extends TermSerializer subterms(i)=t cbc = nbc } - (StructuredTerm(ts,subterms.toIndexedSeq,emptyAttributes,termSystem), cbc) + (StructuredTerm(ts,subterms.toIndexedSeq,emptyAttributes), cbc) } private def writeVar(t: VarTerm, bc: BlockContext, out: Output): BlockContext = @@ -181,7 +178,7 @@ trait Serializer extends TermSerializer val name = readName(in) val varIndex = in.readInt() val scopeIndex = in.readInt - VarTerm(name=name,varIndex,scopeIndex,Map(),termSystem) + VarTerm(name=name,varIndex,scopeIndex,Map()) } def writeName(name:Name, out: Output): Unit = @@ -248,7 +245,3 @@ trait Serializer extends TermSerializer } -object Serializer extends Serializer -{ - def termSystem = FreeTermSystem -} diff --git a/src/main/scala/termware/free/Unification.scala b/src/main/scala/termware/free/Unification.scala index 09e9ba1..6f5bfa6 100644 --- a/src/main/scala/termware/free/Unification.scala +++ b/src/main/scala/termware/free/Unification.scala @@ -10,15 +10,15 @@ object Unification extends termware.Unification def apply(x: TermWithContext, y: TermWithContext, scope: Term): Match = { x.term match { - case AtomTerm(xv,xa,xts) => + case AtomTerm(xv,xa) => y.term match { - case AtomTerm(yv,ya,yts) => + case AtomTerm(yv,ya) => if (xv == yv) { Substitution.empty } else { MatchFailure(x,y,"different atoms") } - case VarTerm(yn,yi,ys,xa,ts) => + case VarTerm(yn,yi,ys,xa) => if (y.scope.forall(_ eq scope)) { Substitution(Map(y->x)) } else { @@ -30,7 +30,7 @@ object Unification extends termware.Unification case px:PrimitiveTerm => y.term match { case py:PrimitiveTerm => applyPrimitive(px,py,x,y) - case VarTerm(yn,yi,ys,xa,ts) => + case VarTerm(yn,yi,ys,xa) => if (y.scope.forall(_ eq scope)) { Substitution(Map(y->x)) } else { @@ -39,9 +39,9 @@ object Unification extends termware.Unification case _ => MatchFailure(x,y,"can't unify primitive with non-primitive") } - case StructuredTerm(xstructure,xcomponents,xa,xts) => + case StructuredTerm(xstructure,xcomponents,xa) => y.term match { - case StructuredTerm(ystructure,ycomponents,ya,yts) => + case StructuredTerm(ystructure,ycomponents,ya) => if (ystructure.name != ystructure.name) { MatchFailure(x,y,"name mismatch") } else if (xcomponents.length != ycomponents.length) { @@ -52,7 +52,7 @@ object Unification extends termware.Unification (x.components zip y.components).foldLeft(s0){ (s,e) => s.merge(apply(e._1,e._2,scope),this,scope) } } - case VarTerm(yn,yi,ys,xa,ts) => + case VarTerm(yn,yi,ys,xa) => if (y.scope.forall(_ eq scope)) { Substitution(Map(y->x)) } else { @@ -61,12 +61,12 @@ object Unification extends termware.Unification case _ => MatchFailure(x,y,"structure mismatch") } - case VarTerm(xn,xi,xs,xa,ts) => + case VarTerm(xn,xi,xs,xa) => if (x.scope.forall(_ eq scope)) { Substitution(Map(x->y)) } else { y.term match { - case VarTerm(yn,yi,ys,xa,ts) => + case VarTerm(yn,yi,ys,xa) => if (y.scope.forall(_ eq scope)) { Substitution(Map(y->x)) } else if ( (y.scope.get eq x.scope.get) && xi == yi) { @@ -84,49 +84,49 @@ object Unification extends termware.Unification def applyPrimitive(x: PrimitiveTerm, y: PrimitiveTerm, xc: TermWithContext, yc: TermWithContext): Match = x match { - case StringTerm(xv,xa,xts) => + case StringTerm(xv,xa) => y match { - case StringTerm(yv,ya,yts) => + case StringTerm(yv,ya) => if (xv == yv) Substitution.empty else MatchFailure(xc,yc,"string mismatch") case _ => MatchFailure(xc,yc,"type mismatch") } - case CharTerm(xv,xa,xts) => + case CharTerm(xv,xa) => y match { - case CharTerm(yv,ya,yts) => + case CharTerm(yv,ya) => if (xv == yv) Substitution.empty else MatchFailure(xc,yc,"char mismatch") case _ => MatchFailure(xc,yc,"type mismatch") } - case Int32Term(xv,xa,xts) => + case Int32Term(xv,xa) => y match { - case Int32Term(yv,ya,yts) => + case Int32Term(yv,ya) => if (xv == yv) Substitution.empty else MatchFailure(xc,yc,"int32 mismatch") case _ => MatchFailure(xc,yc,"type mismatch") } - case Int64Term(xv,xa,xts) => + case Int64Term(xv,xa) => y match { - case Int64Term(yv,ya,yts) => + case Int64Term(yv,ya) => if (xv == yv) Substitution.empty else MatchFailure(xc,yc,"int64 mismatch") case _ => MatchFailure(xc,yc,"type mismatch") } - case DoubleTerm(xv,xa,xts) => + case DoubleTerm(xv,xa) => y match { - case DoubleTerm(yv,ya,yts) => + case DoubleTerm(yv,ya) => if (xv == yv) Substitution.empty else MatchFailure(xc,yc,"double mismatch") case _ => MatchFailure(xc,yc,"type mismatch") } - case OpaqueTerm(xv,xa,xts) => + case OpaqueTerm(xv,xa) => y match { - case OpaqueTerm(yv,ya,yts) => + case OpaqueTerm(yv,ya) => if (xv == yv) Substitution.empty else MatchFailure(xc,yc,"double mismatch") case _ => diff --git a/src/main/scala/termware/package.scala b/src/main/scala/termware/package.scala new file mode 100644 index 0000000..d004fad --- /dev/null +++ b/src/main/scala/termware/package.scala @@ -0,0 +1,7 @@ +package termware + +object `package` { + + def throwPE(s:String):Nothing = throw new ProcessingException(s) + +} From 2ec3be9342ec59b4db8ec111546ad4750ff7902e Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 9 Jan 2016 01:36:23 +0200 Subject: [PATCH 24/27] rethinkign ot term satructure --- src/main/scala/termware/FreeTermSystem.scala | 3 ++ src/main/scala/termware/Match.scala | 1 + .../scala/termware/ProcessingException.scala | 9 +++- src/main/scala/termware/Term.scala | 2 +- src/main/scala/termware/TermContext.scala | 6 +-- src/main/scala/termware/TermOps.scala | 12 ++--- src/main/scala/termware/TermStructure.scala | 38 +++++++++++---- src/main/scala/termware/TermSystem.scala | 4 +- src/main/scala/termware/TermVM.scala | 16 +++++++ src/main/scala/termware/TermWithContext.scala | 3 ++ src/main/scala/termware/TrackedResult.scala | 48 +++++++++++++++++++ .../scala/termware/free/FreeTermContext.scala | 5 ++ src/main/scala/termware/package.scala | 2 + 13 files changed, 125 insertions(+), 24 deletions(-) create mode 100644 src/main/scala/termware/TermVM.scala create mode 100644 src/main/scala/termware/TrackedResult.scala diff --git a/src/main/scala/termware/FreeTermSystem.scala b/src/main/scala/termware/FreeTermSystem.scala index 0b56247..6daa992 100644 --- a/src/main/scala/termware/FreeTermSystem.scala +++ b/src/main/scala/termware/FreeTermSystem.scala @@ -12,5 +12,8 @@ object FreeTermSystem extends TermSystem override def isFree: Boolean = true + // TODO: rethink + override def createVM: TermVM = ??? + } diff --git a/src/main/scala/termware/Match.scala b/src/main/scala/termware/Match.scala index f511f38..7bd858a 100644 --- a/src/main/scala/termware/Match.scala +++ b/src/main/scala/termware/Match.scala @@ -5,6 +5,7 @@ sealed trait Match def put(x:TermWithContext ,y:TermWithContext, u: Unification, s: Term): Match // ts ? def merge(x: Match, u: Unification, s:Term): Match + } diff --git a/src/main/scala/termware/ProcessingException.scala b/src/main/scala/termware/ProcessingException.scala index d12e5fc..b542300 100644 --- a/src/main/scala/termware/ProcessingException.scala +++ b/src/main/scala/termware/ProcessingException.scala @@ -1,9 +1,14 @@ package termware -class ProcessingException(s:String,e:Throwable) extends RuntimeException(s,e) +class ProcessingException( + val message:String, + val tracking: Seq[String], + val cause:Throwable) extends RuntimeException(message,cause) { - def this(s:String) = this(s, null) + def this(message:String) = this(message, Seq(), null) + def this(message:String, tracking:Seq[String]) = this(message, tracking, null) + } diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 5d38a8b..4fd578a 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -74,7 +74,7 @@ case class StructuredTerm( object StructuredTerm { def apply(n:Name, components: IndexedSeq[Term]): StructuredTerm = - StructuredTerm(SeqTermStructure(n,false),components) + StructuredTerm(SeqTermStructure(n),components) } case class VarTerm(val name: Name, diff --git a/src/main/scala/termware/TermContext.scala b/src/main/scala/termware/TermContext.scala index 9e75077..f3f5813 100644 --- a/src/main/scala/termware/TermContext.scala +++ b/src/main/scala/termware/TermContext.scala @@ -3,13 +3,11 @@ package termware trait TermContext { - def scope(source: Term, index:Int):Term - def termSystem(): TermSystem - // def variable(scopeIndex:Int, varIndex:Int):VarTerm + def scope(source: Term, index:Int):Term - // def resolve(name:Name):Option[VarTerm] + def resolve(source: Term, name:Term): TrackedResult[Term] def childContext(term: Term, parent: TermWithContext): TermContext diff --git a/src/main/scala/termware/TermOps.scala b/src/main/scala/termware/TermOps.scala index c6e4209..e1779a2 100644 --- a/src/main/scala/termware/TermOps.scala +++ b/src/main/scala/termware/TermOps.scala @@ -4,17 +4,17 @@ trait TermOps { this: Term => - def name: Name + def name: Name - def arity: Int + def arity: Int - def componentName(i:Int): Option[Name] + def componentName(i: Int): Option[Name] - def componentIndex(n:Name): Option[Int] + def componentIndex(n: Name): Option[Int] - def component(i: Int): Option[Term] + def component(i: Int): Option[Term] - def component(n: Name): Option[Term] + def component(n: Name): Option[Term] def isScope: Boolean diff --git a/src/main/scala/termware/TermStructure.scala b/src/main/scala/termware/TermStructure.scala index 36d0335..40c2d53 100644 --- a/src/main/scala/termware/TermStructure.scala +++ b/src/main/scala/termware/TermStructure.scala @@ -8,21 +8,31 @@ import util._ sealed trait TermStructure { - def name: Name def componentIndex(name:Name): Option[Int] def componentName(i: Int): Option[Name] + // def component(i:Int, t:Term): Option[Term] +//:w + // def component(n:Name, t:Term): Option[Term] = + // componentIndex(n).flatMap(component(_,t)) + /** * is this term define a scope ? */ def isScope: Boolean + def varIndex(name:Name): Option[Int] + } -case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name], isScope: Boolean) extends TermStructure +/** + * default term structure + * TODO: add vars + **/ +case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) extends TermStructure { val componentIndexes = componentNames.foldLeft(Map[Name,Int]()){ (s,e) => s.updated(e,s.size+1) } @@ -34,6 +44,10 @@ case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name], isS Some(componentNames(i)) } else None + def isScope: Boolean = false + + def varIndex(name:Name): Option[Int] = None + } object DefaultTermStructure @@ -41,7 +55,7 @@ object DefaultTermStructure val typeIndex = 1 } -case class SeqTermStructure(name:Name, isScope: Boolean) extends TermStructure +case class SeqTermStructure(name:Name) extends TermStructure { override def componentIndex(name:Name): Option[Int] = @@ -52,6 +66,10 @@ case class SeqTermStructure(name:Name, isScope: Boolean) extends TermStructure override def componentName(i:Int): Option[Name] = Some(IntName(i)) + def isScope: Boolean = false + + def varIndex(name:Name): Option[Int] = None + } object SeqTermStructure @@ -65,9 +83,9 @@ object TermStructure def write(ts: TermStructure, out:Output): Unit = { ts match { - case DefaultTermStructure(name,components,isScope) => + case DefaultTermStructure(name,components) => out.writeInt(DefaultTermStructure.typeIndex) - out.writeBoolean(isScope) + //out.writeBoolean(isScope) free.Serializer.writeName(ts.name,out) val nComponents = components.size out.writeInt(nComponents) @@ -75,9 +93,9 @@ object TermStructure val component = components(i) free.Serializer.writeName(component,out) } - case SeqTermStructure(name,isScope) => + case SeqTermStructure(name) => out.writeInt(SeqTermStructure.typeIndex) - out.writeBoolean(isScope) + //out.writeBoolean(isScope) free.Serializer.writeName(ts.name,out) } } @@ -85,7 +103,7 @@ object TermStructure def read(in: Input): TermStructure = { val typeIndex = in.readInt - val isScope = (in.readByte != 0) + //val isScope = (in.readByte != 0) val name = free.Serializer.readName(in) typeIndex match { case DefaultTermStructure.typeIndex => @@ -94,9 +112,9 @@ object TermStructure val componentNames = (1 to arity).foldLeft(s0){ (s,i)=> s :+ free.Serializer.readName(in) } - DefaultTermStructure(name,componentNames,isScope) + DefaultTermStructure(name,componentNames) case SeqTermStructure.typeIndex => - SeqTermStructure(name, isScope) + SeqTermStructure(name) case _ => throw new IllegalStateException("Unknown term-structure type index: typeIndex"); } diff --git a/src/main/scala/termware/TermSystem.scala b/src/main/scala/termware/TermSystem.scala index 96eb44a..9ceff4d 100644 --- a/src/main/scala/termware/TermSystem.scala +++ b/src/main/scala/termware/TermSystem.scala @@ -9,13 +9,15 @@ trait TermSystem def unification: Unification = free.Unification - def resolve(name: Term): Option[Term] = ??? // Todo: s/Option/ResolveResult + def resolve(name: Term): TrackedResult[Term] = ??? def storage: TermStorage = ??? // baseTermStorage(name) def serializer: TermSerializer = free.Serializer def isFree: Boolean = false + + def createVM(): TermVM } diff --git a/src/main/scala/termware/TermVM.scala b/src/main/scala/termware/TermVM.scala new file mode 100644 index 0000000..af43e78 --- /dev/null +++ b/src/main/scala/termware/TermVM.scala @@ -0,0 +1,16 @@ +package termware + +trait TermVM +{ + + def put(t: Term) + + def step(): Boolean + + def finalState: Boolean + + def errorState: Boolean + + def result(): TrackedResult[Term] + +} diff --git a/src/main/scala/termware/TermWithContext.scala b/src/main/scala/termware/TermWithContext.scala index 262789a..024ce61 100644 --- a/src/main/scala/termware/TermWithContext.scala +++ b/src/main/scala/termware/TermWithContext.scala @@ -6,6 +6,9 @@ case class TermWithContext(term: Term, context: TermContext) def scope(): Option[Term] = if (term.scopeIndex == -1) None else Some(context.scope(term,term.scopeIndex)) + def scope(index: Int): Term = + context.scope(term, index) + def name: Name = term.name def arity: Int = term.arity diff --git a/src/main/scala/termware/TrackedResult.scala b/src/main/scala/termware/TrackedResult.scala new file mode 100644 index 0000000..cdc8922 --- /dev/null +++ b/src/main/scala/termware/TrackedResult.scala @@ -0,0 +1,48 @@ +package termware + +sealed trait TrackedResult[+A] +{ + def result(): A + def isSuccess: Boolean + def isFailure: Boolean + def tracking() : Seq[String] + + def map[B](f: A=>B): TrackedResult[B] + def flatMap[B](f:A=>TrackedResult[B]): TrackedResult[B] + +} + + +case class TrackedSuccess[+A](override val result: A, override val tracking:Seq[String]) extends TrackedResult[A] +{ + override def isSuccess = true + override def isFailure = false + + override def map[B](f: A=>B) = TrackedSuccess(f(result),tracking) + override def flatMap[B](f: A=>TrackedResult[B]): TrackedResult[B] = + f(result) match { + case TrackedSuccess(bResult, bTracking) => + TrackedSuccess(bResult, tracking ++ bTracking) + case TrackedFailure(message, bTracking) => + TrackedFailure(message, tracking ++ bTracking) + } +} + +case class TrackedFailure(message:String, override val tracking:Seq[String]) extends TrackedResult[Nothing] +{ + override def result(): Nothing = + throwPE("failure",tracking) + + override def isSuccess = false + override def isFailure = true + + override def map[B](f: Nothing => B) = this + override def flatMap[B](f: Nothing => TrackedResult[B]) = this + +} + +object TrackedFailure +{ + def apply(message:String): TrackedFailure = apply(message, Seq()) +} + diff --git a/src/main/scala/termware/free/FreeTermContext.scala b/src/main/scala/termware/free/FreeTermContext.scala index b81d9bb..1f63ab9 100644 --- a/src/main/scala/termware/free/FreeTermContext.scala +++ b/src/main/scala/termware/free/FreeTermContext.scala @@ -3,6 +3,11 @@ package termware.free import termware._ sealed trait FreeTermContext extends TermContext +{ + + override def resolve(source: Term, name: Term): TrackedResult[Term] = TrackedFailure("not iplemented") + +} case class TopLevelTermContext(override val termSystem: TermSystem) extends FreeTermContext { diff --git a/src/main/scala/termware/package.scala b/src/main/scala/termware/package.scala index d004fad..b36f992 100644 --- a/src/main/scala/termware/package.scala +++ b/src/main/scala/termware/package.scala @@ -4,4 +4,6 @@ object `package` { def throwPE(s:String):Nothing = throw new ProcessingException(s) + def throwPE(message:String, tracking: Seq[String]):Nothing = throw new ProcessingException(message, tracking) + } From 5e427d256fee29e40a5d3355930bd0ac131a299f Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Wed, 13 Jan 2016 01:10:06 +0200 Subject: [PATCH 25/27] let context be injected into term. --- doc/stermware.bib | 27 +++++++ doc/stermware.tex | 30 ++++--- src/main/scala/termware/AtomTermOps.scala | 2 + src/main/scala/termware/FreeTermSystem.scala | 4 +- src/main/scala/termware/Match.scala | 10 +-- .../scala/termware/PrimitiveTermOps.scala | 15 +--- src/main/scala/termware/ScopeTermOps.scala | 81 +++++++++++++++++++ .../scala/termware/StructuredTermOps.scala | 14 +++- src/main/scala/termware/Term.scala | 10 ++- src/main/scala/termware/TermBuilder.scala | 39 --------- src/main/scala/termware/TermContext.scala | 14 ---- .../scala/termware/TermEmptyComponents.scala | 10 +++ src/main/scala/termware/TermOps.scala | 12 +++ src/main/scala/termware/TermStructure.scala | 14 +--- src/main/scala/termware/TermSystem.scala | 16 ++-- src/main/scala/termware/TermWithContext.scala | 37 --------- src/main/scala/termware/Unification.scala | 2 +- src/main/scala/termware/VarTermOps.scala | 2 + .../scala/termware/free/FreeTermContext.scala | 42 ---------- .../scala/termware/free/Unification.scala | 54 ++++++------- 20 files changed, 213 insertions(+), 222 deletions(-) create mode 100644 src/main/scala/termware/ScopeTermOps.scala delete mode 100644 src/main/scala/termware/TermBuilder.scala delete mode 100644 src/main/scala/termware/TermContext.scala delete mode 100644 src/main/scala/termware/TermWithContext.scala delete mode 100644 src/main/scala/termware/free/FreeTermContext.scala diff --git a/doc/stermware.bib b/doc/stermware.bib index a94ad94..dd3b372 100644 --- a/doc/stermware.bib +++ b/doc/stermware.bib @@ -33,3 +33,30 @@ @INPROCEEDINGS{Jay05purepattern url = {http://www.pps.univ-paris-diderot.fr/~kesner/papers/revisedpurepattern.pdf} } +@INPROCEEDINGS{RhoCal-Wrla2002, + author = {Cirstea,~Horatiu and Kirchner,~Claude and Liquori,~Luigi}, + title = {Rewriting Calculus with(out) Types}, + booktitle = {Proceedings of the fourth workshop on rewriting logic + and applications}, + year = {2002}, + editor = {Gadducci, Fabio and Montanari, Ugo}, + publisher = {Electronic Notes in Theoretical Computer Science}, + address = {Pisa (Italy)}, + month = SEP, +} + +@article{BravenboerKVV08, + title = {{Stratego/XT 0.17}. {A} language and toolset for program transformation}, + author = {Martin Bravenboer and Karl Trygve Kalleberg and Rob Vermaas and Eelco Visser}, + year = {2008}, + doi = {http://dx.doi.org/10.1016/j.scico.2007.11.003}, + tags = {control systems, programming languages, object-oriented programming, concrete object syntax, reusable components, rule-based, completeness, meta programming, pattern language, graph transformation, Stratego/XT, transformation language, reuse, graph-rewriting, rules, transformation system, DSL, programming, subject-oriented programming, context-aware, abstraction, Meta-Environment, rewriting, rewriting strategies, feature-oriented programming, concrete syntax, meta-objects, transformation, Stratego, program transformation}, + researchr = {http://researchr.org/publication/BravenboerKVV08}, + cites = {0}, + citedby = {7}, + journal = {Science of Computer Programming}, + volume = {72}, + number = {1-2}, + pages = {52-70}, +} + diff --git a/doc/stermware.tex b/doc/stermware.tex index bdd16b4..8f8ae70 100644 --- a/doc/stermware.tex +++ b/doc/stermware.tex @@ -10,6 +10,7 @@ \documentclass[12pt]{article} \usepackage{listings} +\usepackage{amsmath} % "define" Scala \lstdefinelanguage{scala}{ @@ -41,40 +42,40 @@ \section{Motivation} Rule-based deduction and rewriting is a well known techniques. Exists many formalizations, from - to $\rho$-caclulus and pure pattern calculus; and + equational logic to $\rho$-caclulus \cite{RhoCal-Wrla2002} and pure pattern calculus\cite{Jay05purepattern} Few programming languages are build + with + We need compact and clean formalizm for definition of programming language construction. Classical term + rewriting can be used for describing program transformations 'in small', but leave dealing with context out + of scope of analythis. Exists different approaches for solving such issues: program analyzers based on + termware framework \cite{DBLP:journals/fuin/DoroshenkoS06} uses terms enriched by context parameters wich provide + API for quering semantics properties, Statego\cite{BravenboerKVV08} use dynamic context-specific rules. \section{Basic definitions} - Let's build term algebra on top of some set of constants, whuch constists from + Let's build term algebra on top of some set of constants, which constists from \begin{itemize} \item original constants ${c_i} \in C$ Also we will need to distinguish some special subset of constants: atoms ${a_i}$ - \item functional term $f_i \in F$ i.e. if $f \in F, c_i \in C (i \in 1..n)$, then $f(c_{1} \dots c_{n}) \in T$ + \item functional term $f_i \in F$ i.e. if $f \in F, c_i \in T (i \in 1..n)$, then $f(c_{1} \dots c_{n}) \in T$ \item variable terms $x_{i}$ which can be inside variable-bound terms. - \item variable bounds term, i.e. so-called 'with-expressions': $with(x_1,\dots x_n):t$ - \item let terms, i.e. so-called 'let expressions' $let \{ x_i \leftarrow t_i \}_{1\dots n} t \in T$ + \item variable bounds term, i.e. so-called 'with-expressions': $with(x_1 \to t_i,\dots x_n\to t_n):t$ \item rule terms, i. e. so-called 'rule expressions': - $rule(p_1 ; p_2 ; \dots p_n \to r_n : p_{fail})$ + $rule(p_1 \to r_1; p_2 \to r_2 ; \dots p_n \to r_n : p_{fail})$ \item application $a b$ \end{itemize} - Let's define usual term operations: - \begin{itemize} - \item s contains t: $s \cap t$ - \end{itemize} - Transformations: \begin{itemize} \item application reduction - $$ rule(with(x_i):p_i \to r_i, ... ) q = + $$ rule(with(x_i\to x_i):p_i \to r_i, ... ) q = \left\{\begin{array}{l l} - \sigma r_i & if \; \sigma=unify(p_i,q)/x_{i} \\ + \sigma r_i & \text{if $\sigma=\text{unify}(p_i,q)/x_{i}$} \\ p_{fail} & otherwise \\ \end{array} \right\} @@ -92,10 +93,7 @@ \section{Basic definitions} \end{itemize} -\section{Related work} - Pure pattern calculus \cite{Jay05purepattern} is a most close formal system. It's congruent by - price of not \bibliographystyle{abbrv} \bibliography{stermware} diff --git a/src/main/scala/termware/AtomTermOps.scala b/src/main/scala/termware/AtomTermOps.scala index 99c716b..634cc68 100644 --- a/src/main/scala/termware/AtomTermOps.scala +++ b/src/main/scala/termware/AtomTermOps.scala @@ -12,6 +12,8 @@ trait AtomTermOps extends TermEmptyComponents override def scopeIndex = -1 + override def resolve(t: Term) = None + override def isVar = false override def varIndex = -1 diff --git a/src/main/scala/termware/FreeTermSystem.scala b/src/main/scala/termware/FreeTermSystem.scala index 6daa992..248db88 100644 --- a/src/main/scala/termware/FreeTermSystem.scala +++ b/src/main/scala/termware/FreeTermSystem.scala @@ -6,14 +6,14 @@ object FreeTermSystem extends TermSystem def name: Term = new AtomTerm("Free") - override def adopt(t: Term): TermWithContext = ??? + override def adopt(t: Term): Term = ??? override def unification: Unification = free.Unification override def isFree: Boolean = true // TODO: rethink - override def createVM: TermVM = ??? + //override def createVM: TermVM = ??? } diff --git a/src/main/scala/termware/Match.scala b/src/main/scala/termware/Match.scala index 7bd858a..ba65728 100644 --- a/src/main/scala/termware/Match.scala +++ b/src/main/scala/termware/Match.scala @@ -2,17 +2,17 @@ package termware sealed trait Match { - def put(x:TermWithContext ,y:TermWithContext, u: Unification, s: Term): Match + def put(x:Term ,y:Term, u: Unification, s: Term): Match // ts ? def merge(x: Match, u: Unification, s:Term): Match } -case class Substitution(mapping: Map[TermWithContext,TermWithContext]) extends Match +case class Substitution(mapping: Map[Term,Term]) extends Match { - def put(x:TermWithContext, y:TermWithContext, u: Unification, s: Term): Match = + def put(x:Term, y:Term, u: Unification, s: Term): Match = { def updated = Substitution(mapping.updated(x,y)) mapping.get(x) match { @@ -34,10 +34,10 @@ case class Substitution(mapping: Map[TermWithContext,TermWithContext]) extends M } -case class MatchFailure(val x: TermWithContext, val y: TermWithContext, val reason: String) extends Match +case class MatchFailure(val x: Term, val y: Term, val reason: String) extends Match { - def put(x:TermWithContext,y:TermWithContext, u: Unification, s: Term): Match = this + def put(x:Term,y:Term, u: Unification, s: Term): Match = this def merge(x: Match, u: Unification, s:Term ): Match = this diff --git a/src/main/scala/termware/PrimitiveTermOps.scala b/src/main/scala/termware/PrimitiveTermOps.scala index 5e58a17..81bfa1d 100644 --- a/src/main/scala/termware/PrimitiveTermOps.scala +++ b/src/main/scala/termware/PrimitiveTermOps.scala @@ -1,29 +1,18 @@ package termware -trait PrimitiveTermOps +trait PrimitiveTermOps extends TermEmptyComponents { this: PrimitiveTerm => - override def arity = 0 - - override def component(n:Name) = None - - override def component(i:Int) = None - - override def componentName(i:Int) = None - - override def componentIndex(n:Name) = None - override def isVar = false override def varIndex = -1 override def isScoped = false - override def isScope = false - override def scopeIndex = -1 + override def resolve(t: Term) = None } diff --git a/src/main/scala/termware/ScopeTermOps.scala b/src/main/scala/termware/ScopeTermOps.scala new file mode 100644 index 0000000..cd5e90e --- /dev/null +++ b/src/main/scala/termware/ScopeTermOps.scala @@ -0,0 +1,81 @@ +package termware + +trait ScopeTermOps extends TermOps +{ + this: ScopeTerm => + + def arity = body.arity + + def component(n: Name) = body.component(n) map (this.substitute(_)) + def component(i: Int) = body.component(i) map (this.substitute(_)) + + def componentIndex(n: Name): Option[Int] = body.componentIndex(n) + def componentName(i: Int): Option[Name] = body.componentName(i) + + def isScope: Boolean = true + + def isScoped: Boolean = body.isScoped + def isVar: Boolean = + if (body.isVar && body.scopeIndex==scopeIndex) + vars(body.varIndex)._2.isVar + else + false + + def name = body.name + def scopeArity: Int = vars.size + def scopeVar(n: Name): Option[Term] = + varNames.get(n).flatMap(scopeVar(_)) + + def scopeVar(i: Int): Option[Term] = varsi(i) map (_._2) + + def scopeVarIndex(n: Name): Option[Int] = ??? + def scopeVarName(i: Int): Option[Name] = ??? + def varIndex: Int = -1 + + // TODO: generalizw to any term. + def resolve(t:Term): Option[Term] = + { + def resolveSucc(b:Term,t: Term): Term = + { + b.resolve(t).getOrElse(t) + } + if (t.arity == 0) { + scopeVar(t.name) match { + case Some(t1) => Some(resolveSucc(body,t1)) + case None => body.resolve(t) + } + }else{ + //TODO: implement all + None + } + } + + def withAttributes(attributes: Map[Name,Term]): Term = + copy(attributes=attributes) + + private def varsi(i: Int): Option[(VarTerm,Term)] = + if (i t + case x: PrimitiveTerm => t + case x: StructuredTerm => ScopeTerm(scopeIndex,vars,t) + case x: ScopeTerm => ScopeTerm(scopeIndex,vars,t) // TODO: think about implementing mergeScope ? + case x: VarTerm => if (x.scopeIndex == scopeIndex) { + val (m,st) = vars(x.varIndex) + if (st eq x) { + x + }else{ + substitute(st) + } + } else x + } + + + lazy val varNames:Map[Name,Int] = ??? +} diff --git a/src/main/scala/termware/StructuredTermOps.scala b/src/main/scala/termware/StructuredTermOps.scala index 14f2d63..bf740d7 100644 --- a/src/main/scala/termware/StructuredTermOps.scala +++ b/src/main/scala/termware/StructuredTermOps.scala @@ -26,9 +26,21 @@ trait StructuredTermOps extends TermOps override def scopeIndex = -1 + override def scopeArity = 0 + override def isScoped = false - override def isScope = termStructure.isScope + override def resolve(t: Term) = None + + override def isScope = false + + override def scopeVar(n: Name): Option[Term] = None + + override def scopeVar(i: Int): Option[Term] = None + + override def scopeVarIndex(n: Name): Option[Int] = None + + override def scopeVarName(i: Int): Option[Name] = None override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 4fd578a..944dea6 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -14,7 +14,6 @@ case class AtomTerm(value:String, } - sealed trait PrimitiveTerm extends Term with PrimitiveTermOps @@ -62,7 +61,6 @@ case class OpaqueTerm(value: Array[Byte], override val name = OpaqueName(value) } -// TODO: add min/max index. case class StructuredTerm( termStructure: TermStructure, components: IndexedSeq[Term], @@ -77,6 +75,14 @@ object StructuredTerm StructuredTerm(SeqTermStructure(n),components) } +case class ScopeTerm( + scopeIndex: Int, + vars: IndexedSeq[(VarTerm,Term)], + body: Term, + override val attributes: Map[Name,Term] = Map() + ) extends Term with ScopeTermOps + + case class VarTerm(val name: Name, val varIndex: Int, // index in scope. override val scopeIndex: Int = -1, // index of scope. point to diff --git a/src/main/scala/termware/TermBuilder.scala b/src/main/scala/termware/TermBuilder.scala deleted file mode 100644 index 72e6908..0000000 --- a/src/main/scala/termware/TermBuilder.scala +++ /dev/null @@ -1,39 +0,0 @@ -package termware - -// TODO: make one mutable. -case class TermBuilder( - private val parent: Option[TermBuilder], - private val structure: TermStructure, - private val components: IndexedSeq[Term]=IndexedSeq(), - private val scopeIndex: Int, - private val lastScopeIndex: Int, - private val nVariables: Int - ) -{ - - - def startChild(ts: TermStructure) : TermBuilder = - { - val (newScopeIndex, newLastScopeIndex) = if (ts.isScope) { - val newScopeIndex = lastScopeIndex+1 - (newScopeIndex, newScopeIndex) - } else (-1, lastScopeIndex) - new TermBuilder(Some(this),ts,IndexedSeq(), newScopeIndex, newLastScopeIndex, 0) - } - - def finishChild(): TermBuilder = - { - parent.get.addTermWithScope(StructuredTerm(structure,components,Map()),lastScopeIndex) - } - - def addTermWithScope(t: Term, newLastScopeIndex: Int): TermBuilder = - copy(components = components :+ t, lastScopeIndex = lastScopeIndex) - - def addPrimitive(t: PrimitiveTerm): TermBuilder = - copy(components = components :+ t) - - def addAtom(t: AtomTerm): TermBuilder = - copy(components = components :+ t) - - -} diff --git a/src/main/scala/termware/TermContext.scala b/src/main/scala/termware/TermContext.scala deleted file mode 100644 index f3f5813..0000000 --- a/src/main/scala/termware/TermContext.scala +++ /dev/null @@ -1,14 +0,0 @@ -package termware - -trait TermContext -{ - - def termSystem(): TermSystem - - def scope(source: Term, index:Int):Term - - def resolve(source: Term, name:Term): TrackedResult[Term] - - def childContext(term: Term, parent: TermWithContext): TermContext - -} diff --git a/src/main/scala/termware/TermEmptyComponents.scala b/src/main/scala/termware/TermEmptyComponents.scala index 085f715..8549c6a 100644 --- a/src/main/scala/termware/TermEmptyComponents.scala +++ b/src/main/scala/termware/TermEmptyComponents.scala @@ -18,5 +18,15 @@ trait TermEmptyComponents override def isScope = true + override def scopeArity = 0 + + override def scopeVar(n: Name) = None + + override def scopeVar(i: Int) = None + + override def scopeVarIndex(n: Name) = None + + override def scopeVarName(i: Int) = None + } diff --git a/src/main/scala/termware/TermOps.scala b/src/main/scala/termware/TermOps.scala index e1779a2..a7b166c 100644 --- a/src/main/scala/termware/TermOps.scala +++ b/src/main/scala/termware/TermOps.scala @@ -18,8 +18,20 @@ trait TermOps def isScope: Boolean + def scopeArity: Int + + def scopeVar(i: Int): Option[Term] + + def scopeVar(n: Name): Option[Term] + + def scopeVarName(i: Int): Option[Name] + + def scopeVarIndex(n: Name): Option[Int] + def isScoped: Boolean + def resolve(t: Term): Option[Term] + def scopeIndex: Int def isVar: Boolean diff --git a/src/main/scala/termware/TermStructure.scala b/src/main/scala/termware/TermStructure.scala index 40c2d53..14cca26 100644 --- a/src/main/scala/termware/TermStructure.scala +++ b/src/main/scala/termware/TermStructure.scala @@ -14,23 +14,15 @@ sealed trait TermStructure def componentName(i: Int): Option[Name] - // def component(i:Int, t:Term): Option[Term] +// def component(i:Int, t:Term): Option[Term] //:w // def component(n:Name, t:Term): Option[Term] = // componentIndex(n).flatMap(component(_,t)) - /** - * is this term define a scope ? - */ - def isScope: Boolean - - def varIndex(name:Name): Option[Int] - } /** * default term structure - * TODO: add vars **/ case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) extends TermStructure { @@ -44,8 +36,6 @@ case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) ext Some(componentNames(i)) } else None - def isScope: Boolean = false - def varIndex(name:Name): Option[Int] = None } @@ -66,8 +56,6 @@ case class SeqTermStructure(name:Name) extends TermStructure override def componentName(i:Int): Option[Name] = Some(IntName(i)) - def isScope: Boolean = false - def varIndex(name:Name): Option[Int] = None } diff --git a/src/main/scala/termware/TermSystem.scala b/src/main/scala/termware/TermSystem.scala index 9ceff4d..8e37eb5 100644 --- a/src/main/scala/termware/TermSystem.scala +++ b/src/main/scala/termware/TermSystem.scala @@ -3,21 +3,17 @@ package termware trait TermSystem { - def name: Term - def adopt(t: Term): TermWithContext = ??? + def name: Term - def unification: Unification = free.Unification + def adopt(t: Term): Term = t - def resolve(name: Term): TrackedResult[Term] = ??? + def unification: Unification = free.Unification - def storage: TermStorage = ??? // baseTermStorage(name) + def storage: TermStorage = ??? - def serializer: TermSerializer = free.Serializer + def serializer: TermSerializer = free.Serializer - def isFree: Boolean = false + def isFree: Boolean = false - def createVM(): TermVM } - - diff --git a/src/main/scala/termware/TermWithContext.scala b/src/main/scala/termware/TermWithContext.scala deleted file mode 100644 index 024ce61..0000000 --- a/src/main/scala/termware/TermWithContext.scala +++ /dev/null @@ -1,37 +0,0 @@ -package termware - -case class TermWithContext(term: Term, context: TermContext) -{ - - def scope(): Option[Term] = - if (term.scopeIndex == -1) None else Some(context.scope(term,term.scopeIndex)) - - def scope(index: Int): Term = - context.scope(term, index) - - def name: Name = term.name - - def arity: Int = term.arity - - def components(): IndexedSeq[TermWithContext] = - { - term match { - case st: StructuredTerm => - st.components map wrapChild - case _ => IndexedSeq() - } - } - - def component(n:Name): Option[TermWithContext] = - term.component(n) map wrapChild - - def component(i:Int): Option[TermWithContext] = - term.component(i) map wrapChild - - - private def wrapChild(c: Term): TermWithContext = - TermWithContext(c, context.childContext(c,this)) - -} - - diff --git a/src/main/scala/termware/Unification.scala b/src/main/scala/termware/Unification.scala index 74a531c..6a764f9 100644 --- a/src/main/scala/termware/Unification.scala +++ b/src/main/scala/termware/Unification.scala @@ -3,6 +3,6 @@ package termware trait Unification { - def apply(x: TermWithContext, y: TermWithContext, scope:Term): Match + def apply(x: Term, y: Term, scope:Term): Match } diff --git a/src/main/scala/termware/VarTermOps.scala b/src/main/scala/termware/VarTermOps.scala index 1f0b38d..34081a0 100644 --- a/src/main/scala/termware/VarTermOps.scala +++ b/src/main/scala/termware/VarTermOps.scala @@ -8,6 +8,8 @@ trait VarTermOps extends TermEmptyComponents override def isScoped = scopeIndex != -1 + override def resolve(t: Term) = None + override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } diff --git a/src/main/scala/termware/free/FreeTermContext.scala b/src/main/scala/termware/free/FreeTermContext.scala deleted file mode 100644 index 1f63ab9..0000000 --- a/src/main/scala/termware/free/FreeTermContext.scala +++ /dev/null @@ -1,42 +0,0 @@ -package termware.free - -import termware._ - -sealed trait FreeTermContext extends TermContext -{ - - override def resolve(source: Term, name: Term): TrackedResult[Term] = TrackedFailure("not iplemented") - -} - -case class TopLevelTermContext(override val termSystem: TermSystem) extends FreeTermContext -{ - - def childContext(term: Term,parent: TermWithContext):TermContext = - ChildTermContext(termSystem, parent) - - def scope(source: Term, index: Int): Term = - if (source.isScope && source.scopeIndex == index) { - source - } else { - throwPE(s"scope ${index} is not not found") - } - -} - -case class ChildTermContext(override val termSystem: TermSystem, val parent: TermWithContext) extends FreeTermContext -{ - - def childContext(term: Term,parent: TermWithContext):TermContext = - ChildTermContext(termSystem, parent) - - def scope(source: Term, index: Int): Term = - if (source.isScope && source.scopeIndex == index) { - source - } else { - parent.context.scope(parent.term, index) - } - - -} - diff --git a/src/main/scala/termware/free/Unification.scala b/src/main/scala/termware/free/Unification.scala index 6f5bfa6..8a46b0b 100644 --- a/src/main/scala/termware/free/Unification.scala +++ b/src/main/scala/termware/free/Unification.scala @@ -7,11 +7,11 @@ object Unification extends termware.Unification // naive recursive implementation. // TODO: rewrite - def apply(x: TermWithContext, y: TermWithContext, scope: Term): Match = + def apply(x: Term, y: Term, scope: Term): Match = { - x.term match { + x match { case AtomTerm(xv,xa) => - y.term match { + y match { case AtomTerm(yv,ya) => if (xv == yv) { Substitution.empty @@ -19,7 +19,7 @@ object Unification extends termware.Unification MatchFailure(x,y,"different atoms") } case VarTerm(yn,yi,ys,xa) => - if (y.scope.forall(_ eq scope)) { + if (y.scopeIndex == scope.scopeIndex) { Substitution(Map(y->x)) } else { MatchFailure(x,y,"can't unify atom and non-with var") @@ -28,10 +28,10 @@ object Unification extends termware.Unification MatchFailure(x,y,"can't unify atom with non-atom") } case px:PrimitiveTerm => - y.term match { - case py:PrimitiveTerm => applyPrimitive(px,py,x,y) + y match { + case py:PrimitiveTerm => applyPrimitive(px,py) case VarTerm(yn,yi,ys,xa) => - if (y.scope.forall(_ eq scope)) { + if (y.scopeIndex == scope.scopeIndex) { Substitution(Map(y->x)) } else { MatchFailure(x,y,"can't unify primitive and non-with var") @@ -40,7 +40,7 @@ object Unification extends termware.Unification MatchFailure(x,y,"can't unify primitive with non-primitive") } case StructuredTerm(xstructure,xcomponents,xa) => - y.term match { + y match { case StructuredTerm(ystructure,ycomponents,ya) => if (ystructure.name != ystructure.name) { MatchFailure(x,y,"name mismatch") @@ -49,11 +49,11 @@ object Unification extends termware.Unification } else { var s0: Match = Substitution.empty // TODO: define components as term-with-context. - (x.components zip y.components).foldLeft(s0){ (s,e) => + (xcomponents zip ycomponents).foldLeft(s0){ (s,e) => s.merge(apply(e._1,e._2,scope),this,scope) } } case VarTerm(yn,yi,ys,xa) => - if (y.scope.forall(_ eq scope)) { + if (y.scopeIndex == scope.scopeIndex) { Substitution(Map(y->x)) } else { MatchFailure(x,y,"can't unify structured term and non-with var") @@ -62,14 +62,14 @@ object Unification extends termware.Unification MatchFailure(x,y,"structure mismatch") } case VarTerm(xn,xi,xs,xa) => - if (x.scope.forall(_ eq scope)) { + if (x.scopeIndex == scope.scopeIndex) { Substitution(Map(x->y)) } else { - y.term match { + y match { case VarTerm(yn,yi,ys,xa) => - if (y.scope.forall(_ eq scope)) { + if (y.scopeIndex == scope.scopeIndex) { Substitution(Map(y->x)) - } else if ( (y.scope.get eq x.scope.get) && xi == yi) { + } else if ( y.scopeIndex == x.scopeIndex && xi == yi) { // TODO: review. Substitution.empty } else { @@ -82,55 +82,55 @@ object Unification extends termware.Unification } } - def applyPrimitive(x: PrimitiveTerm, y: PrimitiveTerm, xc: TermWithContext, yc: TermWithContext): Match = + def applyPrimitive(x: PrimitiveTerm, y: PrimitiveTerm): Match = x match { case StringTerm(xv,xa) => y match { case StringTerm(yv,ya) => if (xv == yv) Substitution.empty - else MatchFailure(xc,yc,"string mismatch") + else MatchFailure(x,y,"string mismatch") case _ => - MatchFailure(xc,yc,"type mismatch") + MatchFailure(x,y,"type mismatch") } case CharTerm(xv,xa) => y match { case CharTerm(yv,ya) => if (xv == yv) Substitution.empty - else MatchFailure(xc,yc,"char mismatch") + else MatchFailure(x,y,"char mismatch") case _ => - MatchFailure(xc,yc,"type mismatch") + MatchFailure(x,y,"type mismatch") } case Int32Term(xv,xa) => y match { case Int32Term(yv,ya) => if (xv == yv) Substitution.empty - else MatchFailure(xc,yc,"int32 mismatch") + else MatchFailure(x,y,"int32 mismatch") case _ => - MatchFailure(xc,yc,"type mismatch") + MatchFailure(x,y,"type mismatch") } case Int64Term(xv,xa) => y match { case Int64Term(yv,ya) => if (xv == yv) Substitution.empty - else MatchFailure(xc,yc,"int64 mismatch") + else MatchFailure(x,y,"int64 mismatch") case _ => - MatchFailure(xc,yc,"type mismatch") + MatchFailure(x,y,"type mismatch") } case DoubleTerm(xv,xa) => y match { case DoubleTerm(yv,ya) => if (xv == yv) Substitution.empty - else MatchFailure(xc,yc,"double mismatch") + else MatchFailure(x,y,"double mismatch") case _ => - MatchFailure(xc,yc,"type mismatch") + MatchFailure(x,y,"type mismatch") } case OpaqueTerm(xv,xa) => y match { case OpaqueTerm(yv,ya) => if (xv == yv) Substitution.empty - else MatchFailure(xc,yc,"double mismatch") + else MatchFailure(x,y,"double mismatch") case _ => - MatchFailure(xc,yc,"type mismatch") + MatchFailure(x,y,"type mismatch") } } From f0e6b00383660d2388cc4dcb53d00860cba68273 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Sat, 30 Jan 2016 18:03:25 +0200 Subject: [PATCH 26/27] added description of matching net. --- doc/stermware.bib | 17 +++++++++ doc/stermware.tex | 91 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 91 insertions(+), 17 deletions(-) diff --git a/doc/stermware.bib b/doc/stermware.bib index dd3b372..3ae1183 100644 --- a/doc/stermware.bib +++ b/doc/stermware.bib @@ -60,3 +60,20 @@ @article{BravenboerKVV08 pages = {52-70}, } +@inproceedings{Pfenning:1988:HAS:53990.54010, + author = {Pfenning, F. and Elliott, C.}, + title = {Higher-order Abstract Syntax}, + booktitle = {Proceedings of the ACM SIGPLAN 1988 Conference on Programming Language Design and Implementation}, + series = {PLDI '88}, + year = {1988}, + isbn = {0-89791-269-1}, + location = {Atlanta, Georgia, USA}, + pages = {199--208}, + numpages = {10}, + url = {http://doi.acm.org/10.1145/53990.54010}, + doi = {10.1145/53990.54010}, + acmid = {54010}, + publisher = {ACM}, + address = {New York, NY, USA}, +} + diff --git a/doc/stermware.tex b/doc/stermware.tex index 8f8ae70..818f0a4 100644 --- a/doc/stermware.tex +++ b/doc/stermware.tex @@ -11,6 +11,9 @@ \documentclass[12pt]{article} \usepackage{listings} \usepackage{amsmath} +\usepackage{pgf} +\usepackage{tikz} +\usetikzlibrary{arrows,automata} % "define" Scala \lstdefinelanguage{scala}{ @@ -48,11 +51,12 @@ \section{Motivation} We need compact and clean formalizm for definition of programming language construction. Classical term rewriting can be used for describing program transformations 'in small', but leave dealing with context out - of scope of analythis. Exists different approaches for solving such issues: program analyzers based on + of scope of analysis. Exists different approaches for solving such issues: program analyzers based on termware framework \cite{DBLP:journals/fuin/DoroshenkoS06} uses terms enriched by context parameters wich provide API for quering semantics properties, Statego\cite{BravenboerKVV08} use dynamic context-specific rules. - - + + Another approaches is hight order abstract syntax\cite{Pfenning:1988:HAS:53990.54010}: AST with binding information encoded as lambda terms, where binded names represented as binded variables. + \section{Basic definitions} @@ -63,9 +67,10 @@ \section{Basic definitions} will need to distinguish some special subset of constants: atoms ${a_i}$ \item functional term $f_i \in F$ i.e. if $f \in F, c_i \in T (i \in 1..n)$, then $f(c_{1} \dots c_{n}) \in T$ \item variable terms $x_{i}$ which can be inside variable-bound terms. - \item variable bounds term, i.e. so-called 'with-expressions': $with(x_1 \to t_i,\dots x_n\to t_n):t$ - \item rule terms, i. e. so-called 'rule expressions': - $rule(p_1 \to r_1; p_2 \to r_2 ; \dots p_n \to r_n : p_{fail})$ + \item rule terms in form $\eta x_1 \dots x_n : p_{1} \to r_1 | p_2 \to r_2 | \dots ! p_{k}$ + %\item variable bounds term, i.e. so-called 'with-expressions': $with(x_1 \to t_i,\dots x_n\to t_n):t$ + %\item rule terms, i. e. so-called 'rule expressions': + % $rule(p_1 \to r_1; p_2 \to r_2 ; \dots p_n \to r_n : p_{fail})$ \item application $a b$ \end{itemize} @@ -73,26 +78,78 @@ \section{Basic definitions} \begin{itemize} \item application reduction - $$ rule(with(x_i\to x_i):p_i \to r_i, ... ) q = + $$ (\eta x_j : p_i \to r_i| \dots ! p_{fail} ) q = \left\{\begin{array}{l l} \sigma r_i & \text{if $\sigma=\text{unify}(p_i,q)/x_{i}$} \\ p_{fail} & otherwise \\ \end{array} \right\} $$ - \item with propagation - $$ with(x):rule(p_1 \dots p_{n}, p_{fail}) = - rule(with(x,p_1) \dots with(x,p_{n}), with(p_{fail})) = - $$ - \item with chaining - $$ with(x_1 \dots x_n):with(y_1 \dots y_n):p = - with(x_1 \dots x_n, y_1 \dots y_n):p $$ - \item with variable elimination - $$ with(x_{1} \dots x_{i} \dots x_{n}):p = - with(x_{1} \dots x_{i-1}, x_{i+1}, \dots x_{n})p \; if x_i \not\in p $$ \end{itemize} +\subsection{ Matching Net } + + For effecient + +for example, next term + +$$ + \begin{aligned} + \eta x, y: & f(x,g(y),x) \to {p_1}(x,y) | \\ + & f(x,x,x) \to {p_2}(x) | \\ + & f(x,y,x) \to {p_3}(x,y) | \\ + & g(y) \to y | \\ + & x \to A \\ + \end{aligned} +$$ + + will be represented by matching net, shown below: + +\begin{tikzpicture}[->,>=stealth',auto,node distance=2.5cm] + + \node(initial, state) (I) { $I$ }; + \node(state) (3) [below right of=I] { $*(*,*,*)$ }; + \node(state) (3fx) [below of=3] { $f(x,*,*)$ }; + \node(state) (3fx1) [below right of =3fx ] { $f(x,*(*),*)$ }; + \node(state) (3fx1gy) [below of =3fx1 ] { $f(x,g(y),*)$ }; + \node(state) (3fx1gyx) [below right of=3fx1gy] {$f(x,g(y),x) \to p_1(x,y)$ }; + \node(state) (3fxx) [below left of=3fx] { $f(x,x,*)$ }; + \node(state) (3fxxx) [below left of=3fxx] { $f(x,x,x) \to p_2(x)$ }; + \node(state) (3fxy) [below of=3fxx] { $f(x,y,*)$ }; + \node(state) (F) [right of=3] { $x \to A$ }; + \node(state) (3fxyx) [ below of=3fxy ] { $f(x,y,x)\to p_3(x,y)$ }; + + + \node(state) (1) [below left of=I] { $*(*)$ }; + \node(state) (1gy) [below left of=1] { $g(y) \to y$ }; + + + \path[font=\scriptsize] + (I) edge node { arity=3 } (3) + edge node { arity=1 } (1) + edge [dotted] node { } (F) + (3) edge node { $name=f$ } (3fx) + edge [dotted] node { } (F) + (3fx) edge node { $2:arity=1$ } (3fx1) + edge node { $2:unify(x)$ } (3fxx) + edge [dotted] node { } (3fxy) + (3fxx) edge node { $3:unify(x)$} (3fxxx) + edge [bend left,dotted] node { } (F) + (3fx1) edge node {2:name==g } (3fx1gy) + edge [bend left, dotted] node { } (3fxy) + (3fxy) edge node {$3:unify(x)$} (3fxyx) + edge [bend left,dotted] node { } (F) + (3fx1gy) edge node {3:unify(x)} (3fx1gyx) + edge [bend right,dotted] node { } (F) + (1) edge node {$name=g$} (1gy) + edge [bend right,dotted] node {fail} (F) + + ; + +\end{tikzpicture} + + Here, each node match imply one lookup (via arity or via name) and then match the rest of target term with the received node; on success we will reach termination node; on failure -- exclude looked patch from possible termination and retry unification until termination patch will be found or all possible forward patched exhausted. If not forward unification is possible in the given node - navigate to next candidate via fallback edge (which are shown as dotted on the scheme). \bibliographystyle{abbrv} From 3aae91078c8ad0ed1a7affe5256270d5ef1d9ef4 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Mon, 2 Jan 2017 22:45:36 +0200 Subject: [PATCH 27/27] 1-st snap implementation --- build.sbt | 5 +- doc/stermware.tex | 81 +++++- src/main/scala/termware/ArrowTermOps.scala | 13 + src/main/scala/termware/AtomTermOps.scala | 19 +- src/main/scala/termware/CharTermOps.scala | 9 +- src/main/scala/termware/ContextTermOps.scala | 11 + src/main/scala/termware/DoubleTermOps.scala | 7 +- src/main/scala/termware/EmptySetTermOps.scala | 12 + src/main/scala/termware/ErrorTermOps.scala | 10 + src/main/scala/termware/FreeTermSystem.scala | 19 -- src/main/scala/termware/Int32TermOps.scala | 6 +- src/main/scala/termware/Int64TermOps.scala | 8 +- src/main/scala/termware/Match.scala | 50 ---- src/main/scala/termware/Name.scala | 30 ++- src/main/scala/termware/NumericTermOps.scala | 7 +- src/main/scala/termware/OpaqueTermOps.scala | 5 +- .../scala/termware/PrimitiveTermOps.scala | 13 +- .../scala/termware/ProcessingException.scala | 14 - src/main/scala/termware/ScopeTermOps.scala | 81 ------ src/main/scala/termware/SetTermOps.scala | 11 + src/main/scala/termware/StringTermOps.scala | 7 +- .../scala/termware/StructuredTermOps.scala | 40 +-- src/main/scala/termware/Term.scala | 96 ++----- src/main/scala/termware/TermAttributes.scala | 11 - src/main/scala/termware/TermCardinality.scala | 26 ++ .../scala/termware/TermEmptyComponents.scala | 32 --- src/main/scala/termware/TermOps.scala | 36 +-- src/main/scala/termware/TermSerializer.scala | 12 - src/main/scala/termware/TermStorage.scala | 11 - src/main/scala/termware/TermStructure.scala | 54 +--- src/main/scala/termware/TermSystem.scala | 19 -- src/main/scala/termware/TermVM.scala | 16 -- src/main/scala/termware/TrackedResult.scala | 48 ---- src/main/scala/termware/UniTermOps.scala | 14 + src/main/scala/termware/Unification.scala | 8 - .../scala/termware/UniversumTermOps.scala | 12 + src/main/scala/termware/VarTermOps.scala | 15 -- src/main/scala/termware/free/Serializer.scala | 247 ------------------ .../scala/termware/free/Unification.scala | 138 ---------- src/main/scala/termware/package.scala | 9 - 40 files changed, 279 insertions(+), 983 deletions(-) create mode 100644 src/main/scala/termware/ArrowTermOps.scala create mode 100644 src/main/scala/termware/ContextTermOps.scala create mode 100644 src/main/scala/termware/EmptySetTermOps.scala create mode 100644 src/main/scala/termware/ErrorTermOps.scala delete mode 100644 src/main/scala/termware/FreeTermSystem.scala delete mode 100644 src/main/scala/termware/Match.scala delete mode 100644 src/main/scala/termware/ProcessingException.scala delete mode 100644 src/main/scala/termware/ScopeTermOps.scala create mode 100644 src/main/scala/termware/SetTermOps.scala delete mode 100644 src/main/scala/termware/TermAttributes.scala create mode 100644 src/main/scala/termware/TermCardinality.scala delete mode 100644 src/main/scala/termware/TermEmptyComponents.scala delete mode 100644 src/main/scala/termware/TermSerializer.scala delete mode 100644 src/main/scala/termware/TermStorage.scala delete mode 100644 src/main/scala/termware/TermSystem.scala delete mode 100644 src/main/scala/termware/TermVM.scala delete mode 100644 src/main/scala/termware/TrackedResult.scala create mode 100644 src/main/scala/termware/UniTermOps.scala delete mode 100644 src/main/scala/termware/Unification.scala create mode 100644 src/main/scala/termware/UniversumTermOps.scala delete mode 100644 src/main/scala/termware/VarTermOps.scala delete mode 100644 src/main/scala/termware/free/Serializer.scala delete mode 100644 src/main/scala/termware/free/Unification.scala delete mode 100644 src/main/scala/termware/package.scala diff --git a/build.sbt b/build.sbt index 1d37bf2..2468561 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ name:="termware" organization:="com.github.termware" -scalaVersion := "2.11.7" +scalaVersion := "2.12.1" scalacOptions ++= Seq("-unchecked","-deprecation","-feature") @@ -11,7 +11,8 @@ version:="0.0.2" libraryDependencies <+= (scalaVersion){ "org.scala-lang" % "scala-reflect" % _ } -libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.1" % "test" +libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test" +//libraryDependencies += "com.github.rssh" %% "trackedfuture" % "0.3" % "test" publishMavenStyle := true diff --git a/doc/stermware.tex b/doc/stermware.tex index 818f0a4..621b0ba 100644 --- a/doc/stermware.tex +++ b/doc/stermware.tex @@ -45,9 +45,7 @@ \section{Motivation} Rule-based deduction and rewriting is a well known techniques. Exists many formalizations, from - equational logic to $\rho$-caclulus \cite{RhoCal-Wrla2002} and pure pattern calculus\cite{Jay05purepattern} Few programming languages are build - with - + equational logic to $\rho$-caclulus \cite{RhoCal-Wrla2002} and pure pattern calculus\cite{Jay05purepattern} Few programming languages are build on top of rule rewriting technique. We need compact and clean formalizm for definition of programming language construction. Classical term rewriting can be used for describing program transformations 'in small', but leave dealing with context out @@ -57,23 +55,86 @@ \section{Motivation} Another approaches is hight order abstract syntax\cite{Pfenning:1988:HAS:53990.54010}: AST with binding information encoded as lambda terms, where binded names represented as binded variables. - + Our proposed approach is an algebra of context-depended term, where operations under term with context are expressed in explicit form. \section{Basic definitions} Let's build term algebra on top of some set of constants, which constists from \begin{itemize} \item original constants ${c_i} \in C$ Also we - will need to distinguish some special subset of constants: atoms ${a_i}$ + will need to distinguish some special subset of constants: atoms ${a_i}$ and also have some special set +of atoms. \item functional term $f_i \in F$ i.e. if $f \in F, c_i \in T (i \in 1..n)$, then $f(c_{1} \dots c_{n}) \in T$ - \item variable terms $x_{i}$ which can be inside variable-bound terms. + %\item variable terms $x_{i}$ which can be inside variable-bound terms. \item rule terms in form $\eta x_1 \dots x_n : p_{1} \to r_1 | p_2 \to r_2 | \dots ! p_{k}$ %\item variable bounds term, i.e. so-called 'with-expressions': $with(x_1 \to t_i,\dots x_n\to t_n):t$ %\item rule terms, i. e. so-called 'rule expressions': % $rule(p_1 \to r_1; p_2 \to r_2 ; \dots p_n \to r_n : p_{fail})$ \item application $a b$ + \item context-terms in form of $context(a,b)$ where $a$ is $rule-term$ which can be delayed operation + \item set-term $\{ t_1 \dots t_2 \}$ which define set of term. Also, let's define special atom for empty + set: $\emptyset$ and for universum $U$ \end{itemize} + And set of usual term operations: + \begin{itemize} + \item subterm: + $$ \left.\begin{array}{l} + subterm(f(t_1,..t_n),i)=x_i \\ + subterm(context(S,t),i)=context(S,subterm(t,i)) \\ + subterm(\{t_1 \dots t_n \},i)=\{subterm(t_1,i), \dots subterm(t_n,i)\} \\ + subterm(F,i)=\emptyset \\ + \end{array}\right. + $$ + \item union: $ x | y = \{ x, y \}$ + $$ \left.\begin{array}{l} + x | \emptyset = x \\ + U | x = U \\ + {x | x } = x \\ + \{ x \to a, x \to b \} = x \to \{a,b\} \\ + \{ x \to a, y \to a \} = \{ x, y\} \to a \\ + context(c,x) | context(c,y) = context(c, x|y) \\ + \end{array}\right. + $$ + also we will identify term and one-element set. + + \item intersection: $ x \& y $ + $$ \left.\begin{array}{l} + x \& \emptyset = \emptyset \\ + U \& x = x \\ + {x \& x } = x \\ + x \to a \& x \to b = x \to a \& b \\ + (a | b ) \& c = a\& c | b\&c \\ + (a \& b ) | c = a\& c | b\&c \\ + \end{array}\right. + $$ + Also usefule will be notation $\langle x_1 \dots x_n \rangle$ wich we will call 'compatible set'. + + + \item substitution and unification: + Note, that in out formalizm substitution and unification results can be represented as ordinary terms + (set of arrows). Also note, that we can any term $t$ repesent as arrow $\emptyset \to t$, by + (let's name on 'substituion term') + $$ subst(x,y) = + \left\{\begin{array}{l l l } + x=\emptyset & & \emptyset \\ + & y=\emptyset & x \\ + x & y=a_{y} \to b_{y} & subst(b_{y},unify(x,a_{y})) \\ + \end{array}\right. + $$ + + $$ unify(x,y) = + \left\{\begin{array}{l l l } + x=\emptyset & & \emptyset \\ + x & \emptyset & \emptyset \\ + c_i \in C & c_j \in C & c_i == c_j \\ + a -> b & & \\ + \end{array}\right. + $$ + + \end{itemize} + + Transformations: \begin{itemize} @@ -85,6 +146,14 @@ \section{Basic definitions} \end{array} \right\} $$ + \item application + $$ + (a->b) c = \left\{ + \begin{array}{l l} + sigma b & \text{ if $\sigma=\text{unify}(a,c) $ } + \end{array}{l l} + \right\} + $$ \end{itemize} diff --git a/src/main/scala/termware/ArrowTermOps.scala b/src/main/scala/termware/ArrowTermOps.scala new file mode 100644 index 0000000..6cb9be1 --- /dev/null +++ b/src/main/scala/termware/ArrowTermOps.scala @@ -0,0 +1,13 @@ +package termware + +trait ArrowTermOps extends TermOps { + + this: ArrowTerm => + + override def name = ArrowName + + override def cardinality = TermCardinality.ONE + + + +} diff --git a/src/main/scala/termware/AtomTermOps.scala b/src/main/scala/termware/AtomTermOps.scala index 634cc68..d538bc3 100644 --- a/src/main/scala/termware/AtomTermOps.scala +++ b/src/main/scala/termware/AtomTermOps.scala @@ -1,24 +1,13 @@ package termware -trait AtomTermOps extends TermEmptyComponents +trait AtomTermOps extends UniTermOps { - this: AtomTerm => - override def isScoped = true - - override def isScope = false - - override def scopeIndex = -1 + override val name = AtomName(value) - override def resolve(t: Term) = None + override def arity: Int = 0 - override def isVar = false - - override def varIndex = -1 - - override def withAttributes(newAttributes: Map[Name,Term]) = - copy(attributes = newAttributes) + override def uniTerm() = this } - diff --git a/src/main/scala/termware/CharTermOps.scala b/src/main/scala/termware/CharTermOps.scala index 62e80eb..69e210a 100644 --- a/src/main/scala/termware/CharTermOps.scala +++ b/src/main/scala/termware/CharTermOps.scala @@ -1,10 +1,9 @@ package termware -trait CharTermOps { +trait CharTermOps extends TermOps +{ + this: CharTerm => - this: CharTerm => - - override def withAttributes(newAttributes: Map[Name,Term]) = - copy(attributes = newAttributes) + override val name = CharName(value) } diff --git a/src/main/scala/termware/ContextTermOps.scala b/src/main/scala/termware/ContextTermOps.scala new file mode 100644 index 0000000..ca88859 --- /dev/null +++ b/src/main/scala/termware/ContextTermOps.scala @@ -0,0 +1,11 @@ +package termware + +trait ContextTermOps extends TermOps +{ + this: ContextTerm => + + override def name = body.name + + override def cardinality = body.cardinality + +} diff --git a/src/main/scala/termware/DoubleTermOps.scala b/src/main/scala/termware/DoubleTermOps.scala index 08a847c..0868733 100644 --- a/src/main/scala/termware/DoubleTermOps.scala +++ b/src/main/scala/termware/DoubleTermOps.scala @@ -1,9 +1,10 @@ package termware -trait DoubleTermOps extends NumericTermOps { +trait DoubleTermOps extends NumericTermOps +{ + this: DoubleTerm => - this: DoubleTerm => + override val name = DoubleName(value) - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) } diff --git a/src/main/scala/termware/EmptySetTermOps.scala b/src/main/scala/termware/EmptySetTermOps.scala new file mode 100644 index 0000000..4ec143f --- /dev/null +++ b/src/main/scala/termware/EmptySetTermOps.scala @@ -0,0 +1,12 @@ +package termware + +trait EmptySetTermOps extends TermOps +{ + + this: EmptySetTerm => + + override def name = SetName + + override def cardinality = TermCardinality.ZERO + +} diff --git a/src/main/scala/termware/ErrorTermOps.scala b/src/main/scala/termware/ErrorTermOps.scala new file mode 100644 index 0000000..4a5fa0f --- /dev/null +++ b/src/main/scala/termware/ErrorTermOps.scala @@ -0,0 +1,10 @@ +package termware + +trait ErrorTermOps extends TermOps +{ + this: ErrorTerm => + + override def name = ErrorName + + override def cardinality = TermCardinality.ERROR +} diff --git a/src/main/scala/termware/FreeTermSystem.scala b/src/main/scala/termware/FreeTermSystem.scala deleted file mode 100644 index 248db88..0000000 --- a/src/main/scala/termware/FreeTermSystem.scala +++ /dev/null @@ -1,19 +0,0 @@ -package termware - - -object FreeTermSystem extends TermSystem -{ - - def name: Term = new AtomTerm("Free") - - override def adopt(t: Term): Term = ??? - - override def unification: Unification = free.Unification - - override def isFree: Boolean = true - - // TODO: rethink - //override def createVM: TermVM = ??? - -} - diff --git a/src/main/scala/termware/Int32TermOps.scala b/src/main/scala/termware/Int32TermOps.scala index 1ccd7c7..19a3d79 100644 --- a/src/main/scala/termware/Int32TermOps.scala +++ b/src/main/scala/termware/Int32TermOps.scala @@ -1,9 +1,9 @@ package termware -trait Int32TermOps extends NumericTermOps { - +trait Int32TermOps extends NumericTermOps +{ this: Int32Term => - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) + override val name = IntName(value) } diff --git a/src/main/scala/termware/Int64TermOps.scala b/src/main/scala/termware/Int64TermOps.scala index 081172e..b52c772 100644 --- a/src/main/scala/termware/Int64TermOps.scala +++ b/src/main/scala/termware/Int64TermOps.scala @@ -1,9 +1,9 @@ package termware -trait Int64TermOps extends NumericTermOps { +trait Int64TermOps extends NumericTermOps +{ + this: Int64Term => - this: Int64Term => - - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) + override val name = LongName(value) } diff --git a/src/main/scala/termware/Match.scala b/src/main/scala/termware/Match.scala deleted file mode 100644 index ba65728..0000000 --- a/src/main/scala/termware/Match.scala +++ /dev/null @@ -1,50 +0,0 @@ -package termware - -sealed trait Match -{ - def put(x:Term ,y:Term, u: Unification, s: Term): Match - // ts ? - def merge(x: Match, u: Unification, s:Term): Match - -} - - -case class Substitution(mapping: Map[Term,Term]) extends Match -{ - - def put(x:Term, y:Term, u: Unification, s: Term): Match = - { - def updated = Substitution(mapping.updated(x,y)) - mapping.get(x) match { - case Some(z) => u(y,z,s) match { - case yz@Substitution(_) => updated.merge(yz,u,s) - case f@MatchFailure(_,_,_) => f - } - case None => updated - } - } - - def merge(x: Match, u: Unification, scope: Term): Match = - x match { - case Substitution(xm) => - val s0: Match = this - xm.foldLeft(s0){ (s,e) => s.put(e._1,e._2,u,scope) } - case f@MatchFailure(_,_,_) => f - } - -} - -case class MatchFailure(val x: Term, val y: Term, val reason: String) extends Match -{ - - def put(x:Term,y:Term, u: Unification, s: Term): Match = this - - def merge(x: Match, u: Unification, s:Term ): Match = this - -} - -object Substitution -{ - val empty = Substitution(Map()) -} - diff --git a/src/main/scala/termware/Name.scala b/src/main/scala/termware/Name.scala index b3a1e20..5124734 100644 --- a/src/main/scala/termware/Name.scala +++ b/src/main/scala/termware/Name.scala @@ -26,13 +26,17 @@ sealed abstract class StringLikeName(val value:String) extends Name object NameTypeIndexes { - val ATOM = 1 - val STRING = 2 - val LONG = 3 + final val ATOM = 1 + final val STRING = 2 + final val LONG = 3 val INT = 4 val CHAR = 5 val DOUBLE = 6 val OPAQUE = 7 + val SET = 8 + val ARROW = 9 + val UNIVERSUM = 10 + val ERROR = 11 } import NameTypeIndexes._ @@ -110,3 +114,23 @@ case class OpaqueName(val value: Array[Byte]) extends Name } +case object SetName extends StringLikeName("set") +{ + def typeIndex = SET +} + +case object ArrowName extends StringLikeName("arrow") +{ + def typeIndex = ARROW +} + +case object UniversumName extends StringLikeName("Universum") +{ + def typeIndex = UNIVERSUM +} + +case object ErrorName extends StringLikeName("Error") +{ + def typeIndex = ERROR +} + diff --git a/src/main/scala/termware/NumericTermOps.scala b/src/main/scala/termware/NumericTermOps.scala index 681288d..b3c07df 100644 --- a/src/main/scala/termware/NumericTermOps.scala +++ b/src/main/scala/termware/NumericTermOps.scala @@ -1,7 +1,6 @@ package termware -trait NumericTermOps { - - this: NumericTerm => - +trait NumericTermOps extends PrimitiveTermOps +{ + this: NumericTerm => } diff --git a/src/main/scala/termware/OpaqueTermOps.scala b/src/main/scala/termware/OpaqueTermOps.scala index 8ea33bc..b7cf474 100644 --- a/src/main/scala/termware/OpaqueTermOps.scala +++ b/src/main/scala/termware/OpaqueTermOps.scala @@ -1,10 +1,9 @@ package termware - trait OpaqueTermOps extends PrimitiveTermOps { - this: OpaqueTerm => - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) + override val name = OpaqueName(value) + } diff --git a/src/main/scala/termware/PrimitiveTermOps.scala b/src/main/scala/termware/PrimitiveTermOps.scala index 81bfa1d..ab813a7 100644 --- a/src/main/scala/termware/PrimitiveTermOps.scala +++ b/src/main/scala/termware/PrimitiveTermOps.scala @@ -1,18 +1,13 @@ package termware - -trait PrimitiveTermOps extends TermEmptyComponents +trait PrimitiveTermOps extends TermOps { - this: PrimitiveTerm => - - override def isVar = false - override def varIndex = -1 + this: PrimitiveTerm => - override def isScoped = false + override def cardinality = TermCardinality.ONE - override def scopeIndex = -1 + override def arity: Int = 0 - override def resolve(t: Term) = None } diff --git a/src/main/scala/termware/ProcessingException.scala b/src/main/scala/termware/ProcessingException.scala deleted file mode 100644 index b542300..0000000 --- a/src/main/scala/termware/ProcessingException.scala +++ /dev/null @@ -1,14 +0,0 @@ -package termware - - -class ProcessingException( - val message:String, - val tracking: Seq[String], - val cause:Throwable) extends RuntimeException(message,cause) -{ - - def this(message:String) = this(message, Seq(), null) - - def this(message:String, tracking:Seq[String]) = this(message, tracking, null) - -} diff --git a/src/main/scala/termware/ScopeTermOps.scala b/src/main/scala/termware/ScopeTermOps.scala deleted file mode 100644 index cd5e90e..0000000 --- a/src/main/scala/termware/ScopeTermOps.scala +++ /dev/null @@ -1,81 +0,0 @@ -package termware - -trait ScopeTermOps extends TermOps -{ - this: ScopeTerm => - - def arity = body.arity - - def component(n: Name) = body.component(n) map (this.substitute(_)) - def component(i: Int) = body.component(i) map (this.substitute(_)) - - def componentIndex(n: Name): Option[Int] = body.componentIndex(n) - def componentName(i: Int): Option[Name] = body.componentName(i) - - def isScope: Boolean = true - - def isScoped: Boolean = body.isScoped - def isVar: Boolean = - if (body.isVar && body.scopeIndex==scopeIndex) - vars(body.varIndex)._2.isVar - else - false - - def name = body.name - def scopeArity: Int = vars.size - def scopeVar(n: Name): Option[Term] = - varNames.get(n).flatMap(scopeVar(_)) - - def scopeVar(i: Int): Option[Term] = varsi(i) map (_._2) - - def scopeVarIndex(n: Name): Option[Int] = ??? - def scopeVarName(i: Int): Option[Name] = ??? - def varIndex: Int = -1 - - // TODO: generalizw to any term. - def resolve(t:Term): Option[Term] = - { - def resolveSucc(b:Term,t: Term): Term = - { - b.resolve(t).getOrElse(t) - } - if (t.arity == 0) { - scopeVar(t.name) match { - case Some(t1) => Some(resolveSucc(body,t1)) - case None => body.resolve(t) - } - }else{ - //TODO: implement all - None - } - } - - def withAttributes(attributes: Map[Name,Term]): Term = - copy(attributes=attributes) - - private def varsi(i: Int): Option[(VarTerm,Term)] = - if (i t - case x: PrimitiveTerm => t - case x: StructuredTerm => ScopeTerm(scopeIndex,vars,t) - case x: ScopeTerm => ScopeTerm(scopeIndex,vars,t) // TODO: think about implementing mergeScope ? - case x: VarTerm => if (x.scopeIndex == scopeIndex) { - val (m,st) = vars(x.varIndex) - if (st eq x) { - x - }else{ - substitute(st) - } - } else x - } - - - lazy val varNames:Map[Name,Int] = ??? -} diff --git a/src/main/scala/termware/SetTermOps.scala b/src/main/scala/termware/SetTermOps.scala new file mode 100644 index 0000000..50be35d --- /dev/null +++ b/src/main/scala/termware/SetTermOps.scala @@ -0,0 +1,11 @@ +package termware + +trait SetTermOps extends TermOps { + + this: SetTerm => + + override def name = SetName + + override def cardinality = TermCardinality.FINITE + +} diff --git a/src/main/scala/termware/StringTermOps.scala b/src/main/scala/termware/StringTermOps.scala index c87413a..8ff9729 100644 --- a/src/main/scala/termware/StringTermOps.scala +++ b/src/main/scala/termware/StringTermOps.scala @@ -1,11 +1,8 @@ package termware - trait StringTermOps extends PrimitiveTermOps { + this: StringTerm => - this: StringTerm => - - override def withAttributes(newAttributes: Map[Name,Term]) = - copy(attributes = newAttributes) + override val name = StringName(value) } diff --git a/src/main/scala/termware/StructuredTermOps.scala b/src/main/scala/termware/StructuredTermOps.scala index bf740d7..473dded 100644 --- a/src/main/scala/termware/StructuredTermOps.scala +++ b/src/main/scala/termware/StructuredTermOps.scala @@ -1,47 +1,13 @@ package termware - trait StructuredTermOps extends TermOps { - this: StructuredTerm => - override def arity = components.length - - override def name = termStructure.name - - override def componentName(i:Int) = termStructure.componentName(i) - - override def componentIndex(n:Name) = termStructure.componentIndex(n) - - override def component(i:Int) = if (i < components.length) { - Some(components(i)) - } else None - - override def component(n:Name) = termStructure.componentIndex(n) map(components(_)) - - override def isVar: Boolean = false - - override def varIndex = -1 - - override def scopeIndex = -1 - - override def scopeArity = 0 - - override def isScoped = false - - override def resolve(t: Term) = None - - override def isScope = false - - override def scopeVar(n: Name): Option[Term] = None - - override def scopeVar(i: Int): Option[Term] = None - - override def scopeVarIndex(n: Name): Option[Int] = None + override val name = termStructure.name - override def scopeVarName(i: Int): Option[Name] = None + override def cardinality: TermCardinality = TermCardinality.ONE - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) + override def arity: Int = components.length } diff --git a/src/main/scala/termware/Term.scala b/src/main/scala/termware/Term.scala index 944dea6..fb774c5 100644 --- a/src/main/scala/termware/Term.scala +++ b/src/main/scala/termware/Term.scala @@ -2,72 +2,17 @@ package termware sealed trait Term extends TermOps -{ - val attributes: Map[Name,Term] = Map() -} - -case class AtomTerm(value:String, - override val attributes: Map[Name,Term] = Map() - ) extends Term with AtomTermOps -{ - override val name = AtomName(value) -} - - -sealed trait PrimitiveTerm extends Term with PrimitiveTermOps - -case class StringTerm(value:String, - override val attributes: Map[Name,Term] = Map() - ) extends PrimitiveTerm with StringTermOps -{ - override val name = StringName(value) -} - -case class CharTerm(value:Character, - override val attributes: Map[Name,Term] = Map() - ) extends PrimitiveTerm with CharTermOps -{ - override val name = CharName(value) -} +sealed trait UniTerm extends Term with UniTermOps -sealed trait NumericTerm extends PrimitiveTerm with NumericTermOps +case class AtomTerm(value:String) extends UniTerm with AtomTermOps -case class Int32Term(value:Int, - override val attributes: Map[Name,Term] = Map() - ) extends NumericTerm with Int32TermOps -{ - override val name = IntName(value) -} - -case class Int64Term(value: Long, - override val attributes: Map[Name,Term] = Map() - ) extends NumericTerm with Int64TermOps -{ - override val name = LongName(value) -} - -case class DoubleTerm(value: Double, - override val attributes: Map[Name,Term] = Map() - ) extends NumericTerm with DoubleTermOps -{ - override val name = DoubleName(value) -} - -case class OpaqueTerm(value: Array[Byte], - override val attributes: Map[Name,Term] = Map() - ) extends PrimitiveTerm with OpaqueTermOps -{ - override val name = OpaqueName(value) -} +sealed trait PrimitiveTerm extends UniTerm with PrimitiveTermOps case class StructuredTerm( termStructure: TermStructure, - components: IndexedSeq[Term], - override val attributes: Map[Name,Term] = Map() - ) extends Term with StructuredTermOps -{ -} + components: IndexedSeq[Term] + ) extends UniTerm with StructuredTermOps object StructuredTerm { @@ -75,20 +20,25 @@ object StructuredTerm StructuredTerm(SeqTermStructure(n),components) } -case class ScopeTerm( - scopeIndex: Int, - vars: IndexedSeq[(VarTerm,Term)], - body: Term, - override val attributes: Map[Name,Term] = Map() - ) extends Term with ScopeTermOps +case class ContextTerm( + scope: SetTerm, + body: Term + ) extends Term with ContextTermOps +class SetTerm(args: Seq[UniTerm]) extends Term with SetTermOps +class EmptySetTerm extends Term with EmptySetTermOps -case class VarTerm(val name: Name, - val varIndex: Int, // index in scope. - override val scopeIndex: Int = -1, // index of scope. point to - override val attributes: Map[Name,Term] = Map() - ) extends Term with VarTermOps -{ -} +case class ArrowTerm(x:Term, y:Term) extends Term with ArrowTermOps + +class UniversumTerm extends Term with UniversumTermOps +class ErrorTerm extends Term with ErrorTermOps +// Primitive terms +case class StringTerm(value:String) extends PrimitiveTerm with StringTermOps +case class CharTerm(value:Character) extends PrimitiveTerm with CharTermOps +sealed trait NumericTerm extends PrimitiveTerm with NumericTermOps +case class Int32Term(value:Int) extends NumericTerm with Int32TermOps +case class Int64Term(value: Long) extends NumericTerm with Int64TermOps +case class DoubleTerm(value: Double) extends NumericTerm with DoubleTermOps +case class OpaqueTerm(value: Array[Byte]) extends PrimitiveTerm with OpaqueTermOps diff --git a/src/main/scala/termware/TermAttributes.scala b/src/main/scala/termware/TermAttributes.scala deleted file mode 100644 index 1762d6a..0000000 --- a/src/main/scala/termware/TermAttributes.scala +++ /dev/null @@ -1,11 +0,0 @@ -package termware - -trait TermAttributed[X] { - -} - -object TermAttributes -{ - val empty: Map[Name,Term] = Map() -} - diff --git a/src/main/scala/termware/TermCardinality.scala b/src/main/scala/termware/TermCardinality.scala new file mode 100644 index 0000000..1c148eb --- /dev/null +++ b/src/main/scala/termware/TermCardinality.scala @@ -0,0 +1,26 @@ +package termware + +import language.implicitConversions + +sealed trait TermCardinality + +case class IntTermCardinality(v:Int) extends TermCardinality + +case object FiniteTermCardinality extends TermCardinality + +case object UniversumTermCardinality extends TermCardinality + +case object ErrorTermCardinality extends TermCardinality + +object TermCardinality +{ + implicit def int2TermCardinality(x:Int):TermCardinality = IntTermCardinality(x) + + final val ONE = IntTermCardinality(1) + final val ZERO = IntTermCardinality(0) + + final val FINITE = FiniteTermCardinality + final val UNIVERSUM = UniversumTermCardinality + final val ERROR = ErrorTermCardinality + +} diff --git a/src/main/scala/termware/TermEmptyComponents.scala b/src/main/scala/termware/TermEmptyComponents.scala deleted file mode 100644 index 8549c6a..0000000 --- a/src/main/scala/termware/TermEmptyComponents.scala +++ /dev/null @@ -1,32 +0,0 @@ -package termware - - -trait TermEmptyComponents -{ - - this: Term => - - override def arity = 0 - - override def component(n:Name) = None - - override def component(i:Int) = None - - override def componentName(i:Int) = None - - override def componentIndex(n:Name) = None - - override def isScope = true - - override def scopeArity = 0 - - override def scopeVar(n: Name) = None - - override def scopeVar(i: Int) = None - - override def scopeVarIndex(n: Name) = None - - override def scopeVarName(i: Int) = None - -} - diff --git a/src/main/scala/termware/TermOps.scala b/src/main/scala/termware/TermOps.scala index a7b166c..3123877 100644 --- a/src/main/scala/termware/TermOps.scala +++ b/src/main/scala/termware/TermOps.scala @@ -4,40 +4,8 @@ trait TermOps { this: Term => - def name: Name + def name: Name - def arity: Int - - def componentName(i: Int): Option[Name] - - def componentIndex(n: Name): Option[Int] - - def component(i: Int): Option[Term] - - def component(n: Name): Option[Term] - - def isScope: Boolean - - def scopeArity: Int - - def scopeVar(i: Int): Option[Term] - - def scopeVar(n: Name): Option[Term] - - def scopeVarName(i: Int): Option[Name] - - def scopeVarIndex(n: Name): Option[Int] - - def isScoped: Boolean - - def resolve(t: Term): Option[Term] - - def scopeIndex: Int - - def isVar: Boolean - - def varIndex: Int - - def withAttributes(attributes: Map[Name,Term]): Term + def cardinality: TermCardinality } diff --git a/src/main/scala/termware/TermSerializer.scala b/src/main/scala/termware/TermSerializer.scala deleted file mode 100644 index 28479d1..0000000 --- a/src/main/scala/termware/TermSerializer.scala +++ /dev/null @@ -1,12 +0,0 @@ -package termware - -import util._ - -trait TermSerializer -{ - - def apply(t: Term, out: Output): Unit - - def unapply(input: Input): Term - -} diff --git a/src/main/scala/termware/TermStorage.scala b/src/main/scala/termware/TermStorage.scala deleted file mode 100644 index a58fe8c..0000000 --- a/src/main/scala/termware/TermStorage.scala +++ /dev/null @@ -1,11 +0,0 @@ -package termware - - -trait TermStorage -{ - - def read(path: String): Term - - def write(path: String, t: Term): Unit - -} diff --git a/src/main/scala/termware/TermStructure.scala b/src/main/scala/termware/TermStructure.scala index 14cca26..2b7d5f0 100644 --- a/src/main/scala/termware/TermStructure.scala +++ b/src/main/scala/termware/TermStructure.scala @@ -14,17 +14,17 @@ sealed trait TermStructure def componentName(i: Int): Option[Name] -// def component(i:Int, t:Term): Option[Term] -//:w - // def component(n:Name, t:Term): Option[Term] = - // componentIndex(n).flatMap(component(_,t)) + def component(i:Int, t: StructuredTerm): Option[Term] = t.components.lift(i) + + def component(n:Name, t:StructuredTerm): Option[Term] = + componentIndex(n).flatMap(component(_,t)) } /** - * default term structure + * simple term structure which consists just from sequence of names **/ -case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) extends TermStructure +case class SimpleTermStructure(name:Name, componentNames: IndexedSeq[Name]) extends TermStructure { val componentIndexes = componentNames.foldLeft(Map[Name,Int]()){ (s,e) => s.updated(e,s.size+1) } @@ -40,7 +40,7 @@ case class DefaultTermStructure(name:Name, componentNames: IndexedSeq[Name]) ext } -object DefaultTermStructure +object SimpleTermStructure { val typeIndex = 1 } @@ -68,44 +68,4 @@ object SeqTermStructure object TermStructure { - def write(ts: TermStructure, out:Output): Unit = - { - ts match { - case DefaultTermStructure(name,components) => - out.writeInt(DefaultTermStructure.typeIndex) - //out.writeBoolean(isScope) - free.Serializer.writeName(ts.name,out) - val nComponents = components.size - out.writeInt(nComponents) - for(i <- 1 to nComponents) { - val component = components(i) - free.Serializer.writeName(component,out) - } - case SeqTermStructure(name) => - out.writeInt(SeqTermStructure.typeIndex) - //out.writeBoolean(isScope) - free.Serializer.writeName(ts.name,out) - } - } - - def read(in: Input): TermStructure = - { - val typeIndex = in.readInt - //val isScope = (in.readByte != 0) - val name = free.Serializer.readName(in) - typeIndex match { - case DefaultTermStructure.typeIndex => - val arity = in.readInt - val s0 = IndexedSeq[Name]() - val componentNames = (1 to arity).foldLeft(s0){ (s,i)=> - s :+ free.Serializer.readName(in) - } - DefaultTermStructure(name,componentNames) - case SeqTermStructure.typeIndex => - SeqTermStructure(name) - case _ => - throw new IllegalStateException("Unknown term-structure type index: typeIndex"); - } - } - } diff --git a/src/main/scala/termware/TermSystem.scala b/src/main/scala/termware/TermSystem.scala deleted file mode 100644 index 8e37eb5..0000000 --- a/src/main/scala/termware/TermSystem.scala +++ /dev/null @@ -1,19 +0,0 @@ -package termware - - -trait TermSystem -{ - - def name: Term - - def adopt(t: Term): Term = t - - def unification: Unification = free.Unification - - def storage: TermStorage = ??? - - def serializer: TermSerializer = free.Serializer - - def isFree: Boolean = false - -} diff --git a/src/main/scala/termware/TermVM.scala b/src/main/scala/termware/TermVM.scala deleted file mode 100644 index af43e78..0000000 --- a/src/main/scala/termware/TermVM.scala +++ /dev/null @@ -1,16 +0,0 @@ -package termware - -trait TermVM -{ - - def put(t: Term) - - def step(): Boolean - - def finalState: Boolean - - def errorState: Boolean - - def result(): TrackedResult[Term] - -} diff --git a/src/main/scala/termware/TrackedResult.scala b/src/main/scala/termware/TrackedResult.scala deleted file mode 100644 index cdc8922..0000000 --- a/src/main/scala/termware/TrackedResult.scala +++ /dev/null @@ -1,48 +0,0 @@ -package termware - -sealed trait TrackedResult[+A] -{ - def result(): A - def isSuccess: Boolean - def isFailure: Boolean - def tracking() : Seq[String] - - def map[B](f: A=>B): TrackedResult[B] - def flatMap[B](f:A=>TrackedResult[B]): TrackedResult[B] - -} - - -case class TrackedSuccess[+A](override val result: A, override val tracking:Seq[String]) extends TrackedResult[A] -{ - override def isSuccess = true - override def isFailure = false - - override def map[B](f: A=>B) = TrackedSuccess(f(result),tracking) - override def flatMap[B](f: A=>TrackedResult[B]): TrackedResult[B] = - f(result) match { - case TrackedSuccess(bResult, bTracking) => - TrackedSuccess(bResult, tracking ++ bTracking) - case TrackedFailure(message, bTracking) => - TrackedFailure(message, tracking ++ bTracking) - } -} - -case class TrackedFailure(message:String, override val tracking:Seq[String]) extends TrackedResult[Nothing] -{ - override def result(): Nothing = - throwPE("failure",tracking) - - override def isSuccess = false - override def isFailure = true - - override def map[B](f: Nothing => B) = this - override def flatMap[B](f: Nothing => TrackedResult[B]) = this - -} - -object TrackedFailure -{ - def apply(message:String): TrackedFailure = apply(message, Seq()) -} - diff --git a/src/main/scala/termware/UniTermOps.scala b/src/main/scala/termware/UniTermOps.scala new file mode 100644 index 0000000..9faba8f --- /dev/null +++ b/src/main/scala/termware/UniTermOps.scala @@ -0,0 +1,14 @@ +package termware + +trait UniTermOps extends TermOps +{ + + this: UniTerm => + + override def cardinality: TermCardinality = TermCardinality.ONE + + def arity: Int + + def uniTerm(): UniTerm = this + +} diff --git a/src/main/scala/termware/Unification.scala b/src/main/scala/termware/Unification.scala deleted file mode 100644 index 6a764f9..0000000 --- a/src/main/scala/termware/Unification.scala +++ /dev/null @@ -1,8 +0,0 @@ -package termware - -trait Unification -{ - - def apply(x: Term, y: Term, scope:Term): Match - -} diff --git a/src/main/scala/termware/UniversumTermOps.scala b/src/main/scala/termware/UniversumTermOps.scala new file mode 100644 index 0000000..9815a51 --- /dev/null +++ b/src/main/scala/termware/UniversumTermOps.scala @@ -0,0 +1,12 @@ +package termware + +trait UniversumTermOps extends TermOps +{ + + this: UniversumTerm => + + override def name = UniversumName + + override def cardinality = TermCardinality.UNIVERSUM + +} diff --git a/src/main/scala/termware/VarTermOps.scala b/src/main/scala/termware/VarTermOps.scala deleted file mode 100644 index 34081a0..0000000 --- a/src/main/scala/termware/VarTermOps.scala +++ /dev/null @@ -1,15 +0,0 @@ -package termware - -trait VarTermOps extends TermEmptyComponents -{ - this: VarTerm => - - override def isVar = true - - override def isScoped = scopeIndex != -1 - - override def resolve(t: Term) = None - - override def withAttributes(newAttributes: Map[Name,Term]) = copy(attributes = newAttributes) - -} diff --git a/src/main/scala/termware/free/Serializer.scala b/src/main/scala/termware/free/Serializer.scala deleted file mode 100644 index 0eabb3c..0000000 --- a/src/main/scala/termware/free/Serializer.scala +++ /dev/null @@ -1,247 +0,0 @@ -package termware.free - -import java.nio._ -import termware._ -import termware.util._ -import termware.TermAttributes.{empty=>emptyAttributes} - -// TODO: write input pos on error. - -object Serializer extends TermSerializer -{ - - def apply(t: Term, out: Output): Unit = - { writeTerm(t,BlockContext(),out) } - - def unapply(in: Input): Term = - readTerm(in,BlockContext())._1 - - case class BlockContext( - val structures: Map[Int, TermStructure] = Map(), - val invStructures: Map[TermStructure, Int] = Map(), - val nextStructureIndex: Int = 0, - val scopes: Map[Int, Term] = Map(), - val invScopes: Map[Term,Int] = Map(), - val nextScopeIndex: Int = 0 - ) { - - def withStructure(structure: TermStructure): (BlockContext, Int) = - { - invStructures.get(structure) match { - case None => val si = nextStructureIndex - val nsi = si+1 - (copy(structures = structures.updated(si, structure), - invStructures = invStructures.updated(structure,si), - nextStructureIndex = nsi), nsi) - case Some(si) => (this, si) - } - } - - def retrieveStructure(i: Int): TermStructure = - structures.get(i).getOrElse(throw new IllegalStateException("Invalid structure index")) - - def withScope(scope: Term): (BlockContext, Int) = - { - invScopes.get(scope) match { - case None => - val si = nextScopeIndex - val nsi = si+1 - (copy(scopes = scopes.updated(si,scope), - invScopes = invScopes.updated(scope,si), - nextScopeIndex = nsi), nsi) - case Some(si) => (this, si) - } - } - - } - - - final val TAG_TERM = 100 - final val TAG_TERMSTRUCTURE = 101 - final val TAG_ATTRIBUTES = 102 - - final val TAG_END = 400 - - - - final val TAG_ATOM = 1; - final val TAG_STRUCTURED=2; - final val TAG_VAR = 3; - - final val TAG_PRIMITIVE = 0x1000; - - - private def writeTerm(t: Term, bc: BlockContext, out: Output): BlockContext = - { - val nbc0 = t match { - case a: AtomTerm => out << TAG_ATOM << a.value ; bc - case p: PrimitiveTerm => writePrimitive(p,out) - case s: StructuredTerm => writeStructured(s,bc,out) - case v: VarTerm => writeVar(v,bc,out) - } - writeAttributes(t.attributes,bc,out) - } - - private def readTerm(in: Input, bc: BlockContext): (Term, BlockContext) = - { - val tag = in.readInt - val (t,nbc0) = tag match { - case TAG_ATOM => (AtomTerm(in.readString,Map()),bc) - case TAG_STRUCTURED => readStructured(in, bc) - case TAG_TERMSTRUCTURE => readTerm(in,readAndAdoptTermStructure(in,bc)) - case TAG_VAR => (readVar(in,bc),bc) - case x if ((x|TAG_PRIMITIVE)!=0) => (readPrimitive(x,in), bc) - case _ => throw new IllegalStateException("Invalid term tag:"+tag) - } - val (attributes, nbc) = readAttributes(in,nbc0) - (t withAttributes attributes, nbc) - } - - - private def writePrimitive(p: PrimitiveTerm, out: Output): Unit = - { - out << (TAG_PRIMITIVE | p.name.typeIndex) - p match { - case StringTerm(v,_) => out << v - case CharTerm(v,_) => out << v - case Int32Term(v,_) => out << v - case Int64Term(v,_) => out << v - case DoubleTerm(v,_) => out << v - case OpaqueTerm(v,_) => (out << v.size).write(v) - } - } - - private def readPrimitive(tag: Int, in: Input): PrimitiveTerm = - { - import NameTypeIndexes._ - (tag & (~TAG_PRIMITIVE)) match { - case STRING => StringTerm(in.readString,Map()) - case CHAR => CharTerm(in.readChar,Map()) - case INT => Int32Term(in.readInt,Map()) - case LONG => Int64Term(in.readLong,Map()) - case DOUBLE => DoubleTerm(in.readDouble(),Map()) - case OPAQUE => OpaqueTerm(in.readOpaque(),Map()) - case _ => throw new IllegalStateException("Invalid primitive tag: "+tag) - } - } - - private def writeStructured(t: StructuredTerm, bc: BlockContext, out: Output): BlockContext = - { - val ts = t.termStructure; - val nextSti = bc.nextStructureIndex - val (nbc0, sti) = bc.withStructure(ts) - if (nextSti == sti) { - out.writeInt(TAG_TERMSTRUCTURE) - out.writeInt(sti) - writeTermStructure(ts,out) - } - val (nbc, sci) = if (t.isScope) { - nbc0 withScope t - } else (nbc0, -1) - out.writeInt(TAG_STRUCTURED) - out.writeInt(sti) - out.writeInt(sci) - out.writeInt(t.arity) - t.components.foldLeft(nbc) { (s,e) => - writeTerm(e,s,out) - } - } - - private def readStructured(in: Input, bc: BlockContext): (Term, BlockContext) = - { - val ts = bc.retrieveStructure(in.readInt) - val sci = in.readInt - if (sci != -1) { - ??? - } - val arity = in.readInt - val subterms = new Array[Term](arity) - var cbc = bc - for(i <- (0 until arity)) { - val (t, nbc) = readTerm(in, cbc) - subterms(i)=t - cbc = nbc - } - (StructuredTerm(ts,subterms.toIndexedSeq,emptyAttributes), cbc) - } - - private def writeVar(t: VarTerm, bc: BlockContext, out: Output): BlockContext = - { - writeName(t.name, out) - out.writeInt(t.varIndex) - out.writeInt(t.scopeIndex) - bc - } - - private def readVar(in: Input, bc: BlockContext): VarTerm = - { - val name = readName(in) - val varIndex = in.readInt() - val scopeIndex = in.readInt - VarTerm(name=name,varIndex,scopeIndex,Map()) - } - - def writeName(name:Name, out: Output): Unit = - { - out.writeInt(name.typeIndex) - name match { - case AtomName(v) => out << v - case StringName(v) => out << v - case CharName(v) => out << v - case LongName(v) => out << v - case IntName(v) => out << v - case DoubleName(v) => out << v - case OpaqueName(v) => out << v - } - } - - - def readName(in: Input): Name = - { - import NameTypeIndexes._ - val typeIndex = in.readInt - typeIndex match { - case ATOM => AtomName(in.readString) - case STRING => StringName(in.readString) - case CHAR => CharName(in.readChar) - case LONG => LongName(in.readLong) - case INT => IntName(in.readInt) - case DOUBLE => DoubleName(in.readDouble) - case OPAQUE => OpaqueName(in.readOpaque) - } - } - - private def writeAttributes(attributes: Map[Name,Term], bc: BlockContext, out: Output): BlockContext = - { - out.writeInt(attributes.size) - attributes.foldLeft(bc){ (s,e) => - writeName(e._1,out) - writeTerm(e._2,s,out) - } - } - - private def readAttributes(in: Input, bc: BlockContext): (Map[Name,Term], BlockContext) = - { - val r: Map[Name,Term] = Map() - val nAttributes = in.readInt - (1 to nAttributes).foldLeft((r,bc)) { (s,i) => - val name = readName(in) - val (t,nbc) = readTerm(in,s._2) - (s._1.updated(name,t),nbc) - } - } - - private def writeTermStructure(ts: TermStructure, out: Output): Unit = - TermStructure.write(ts,out) - - private def readTermStructure(in: Input): TermStructure = - TermStructure.read(in) - - private def readAndAdoptTermStructure(in: Input, bc: BlockContext): BlockContext = - { - val ts = TermStructure.read(in) - (bc withStructure ts)._1 - } - -} - diff --git a/src/main/scala/termware/free/Unification.scala b/src/main/scala/termware/free/Unification.scala deleted file mode 100644 index 8a46b0b..0000000 --- a/src/main/scala/termware/free/Unification.scala +++ /dev/null @@ -1,138 +0,0 @@ -package termware.free - -import termware._ - -object Unification extends termware.Unification -{ - - // naive recursive implementation. - // TODO: rewrite - def apply(x: Term, y: Term, scope: Term): Match = - { - x match { - case AtomTerm(xv,xa) => - y match { - case AtomTerm(yv,ya) => - if (xv == yv) { - Substitution.empty - } else { - MatchFailure(x,y,"different atoms") - } - case VarTerm(yn,yi,ys,xa) => - if (y.scopeIndex == scope.scopeIndex) { - Substitution(Map(y->x)) - } else { - MatchFailure(x,y,"can't unify atom and non-with var") - } - case _ => - MatchFailure(x,y,"can't unify atom with non-atom") - } - case px:PrimitiveTerm => - y match { - case py:PrimitiveTerm => applyPrimitive(px,py) - case VarTerm(yn,yi,ys,xa) => - if (y.scopeIndex == scope.scopeIndex) { - Substitution(Map(y->x)) - } else { - MatchFailure(x,y,"can't unify primitive and non-with var") - } - case _ => - MatchFailure(x,y,"can't unify primitive with non-primitive") - } - case StructuredTerm(xstructure,xcomponents,xa) => - y match { - case StructuredTerm(ystructure,ycomponents,ya) => - if (ystructure.name != ystructure.name) { - MatchFailure(x,y,"name mismatch") - } else if (xcomponents.length != ycomponents.length) { - MatchFailure(x,y,"arity mismatch") - } else { - var s0: Match = Substitution.empty - // TODO: define components as term-with-context. - (xcomponents zip ycomponents).foldLeft(s0){ (s,e) => - s.merge(apply(e._1,e._2,scope),this,scope) } - } - case VarTerm(yn,yi,ys,xa) => - if (y.scopeIndex == scope.scopeIndex) { - Substitution(Map(y->x)) - } else { - MatchFailure(x,y,"can't unify structured term and non-with var") - } - case _ => - MatchFailure(x,y,"structure mismatch") - } - case VarTerm(xn,xi,xs,xa) => - if (x.scopeIndex == scope.scopeIndex) { - Substitution(Map(x->y)) - } else { - y match { - case VarTerm(yn,yi,ys,xa) => - if (y.scopeIndex == scope.scopeIndex) { - Substitution(Map(y->x)) - } else if ( y.scopeIndex == x.scopeIndex && xi == yi) { - // TODO: review. - Substitution.empty - } else { - MatchFailure(x,y,"var mismatch") - } - case _ => - MatchFailure(x,y,"var mismatch") - } - } - } - } - - def applyPrimitive(x: PrimitiveTerm, y: PrimitiveTerm): Match = - x match { - case StringTerm(xv,xa) => - y match { - case StringTerm(yv,ya) => - if (xv == yv) Substitution.empty - else MatchFailure(x,y,"string mismatch") - case _ => - MatchFailure(x,y,"type mismatch") - } - case CharTerm(xv,xa) => - y match { - case CharTerm(yv,ya) => - if (xv == yv) Substitution.empty - else MatchFailure(x,y,"char mismatch") - case _ => - MatchFailure(x,y,"type mismatch") - } - case Int32Term(xv,xa) => - y match { - case Int32Term(yv,ya) => - if (xv == yv) Substitution.empty - else MatchFailure(x,y,"int32 mismatch") - case _ => - MatchFailure(x,y,"type mismatch") - } - case Int64Term(xv,xa) => - y match { - case Int64Term(yv,ya) => - if (xv == yv) Substitution.empty - else MatchFailure(x,y,"int64 mismatch") - case _ => - MatchFailure(x,y,"type mismatch") - } - case DoubleTerm(xv,xa) => - y match { - case DoubleTerm(yv,ya) => - if (xv == yv) Substitution.empty - else MatchFailure(x,y,"double mismatch") - case _ => - MatchFailure(x,y,"type mismatch") - } - case OpaqueTerm(xv,xa) => - y match { - case OpaqueTerm(yv,ya) => - if (xv == yv) Substitution.empty - else MatchFailure(x,y,"double mismatch") - case _ => - MatchFailure(x,y,"type mismatch") - } - } - -} - diff --git a/src/main/scala/termware/package.scala b/src/main/scala/termware/package.scala deleted file mode 100644 index b36f992..0000000 --- a/src/main/scala/termware/package.scala +++ /dev/null @@ -1,9 +0,0 @@ -package termware - -object `package` { - - def throwPE(s:String):Nothing = throw new ProcessingException(s) - - def throwPE(message:String, tracking: Seq[String]):Nothing = throw new ProcessingException(message, tracking) - -}