~ changed sparql.Terms to traits
authorEric Prud'hommeaux <eric@w3.org>
Mon, 08 Feb 2010 09:52:01 -0500
changeset 156 f73ea8909064
parent 154 87829cbc8e29
child 157 8ab6f119e8d8
~ changed sparql.Terms to traits
+ misleading predicate in SparqlToSparql index
src/main/scala/SPARQL.scala
src/main/scala/SparqlToSparql.scala
src/main/scala/SparqlToSql.scala
src/test/scala/SparqlTest.scala
src/test/scala/SparqlToSparqlTest.scala
--- a/src/main/scala/SPARQL.scala	Mon Feb 01 09:15:57 2010 -0500
+++ b/src/main/scala/SPARQL.scala	Mon Feb 08 09:52:01 2010 -0500
@@ -23,7 +23,7 @@
 
 sealed abstract class GraphPattern
 case class TriplesBlock(triplepatterns:List[TriplePattern]) extends GraphPattern {
-  override def toString = "{\n  " + (triplepatterns.toList.map(s => s.toString.replace("\n", "\n  ")).mkString(".\n  "))
+  override def toString = "{\n  " + (triplepatterns.toList.map(s => s.toString.replace("\n", "\n  ")).mkString(".\n  ")) + "\n}"
 }
 case class TableConjunction(gps:List[GraphPattern]) extends GraphPattern {
   assert (!(gps exists (x => { x match { case TableConjunction(_) => true case _ => false } })))
@@ -37,37 +37,10 @@
 case class MinusGraphPattern(gp:GraphPattern) extends GraphPattern
 case class GraphGraphPattern(gp:GraphPattern) extends GraphPattern
 
-case class TriplePattern(s:S, p:P, o:O) {
+case class TriplePattern(s:Term, p:Term, o:Term) {
   override def toString = s + " " + p + " " + o
 }
 
-sealed abstract class S
-case class SUri(u:Uri) extends S {
-  override def toString = "" + u
-}
-case class SVar(v:Var) extends S {
-  override def toString = "" + v
-}
-
-sealed abstract class O
-case class OUri(u:Uri) extends O {
-  override def toString = "" + u
-}
-case class OVar(v:Var) extends O {
-  override def toString = "" + v
-}
-case class OLit(lit:Literal) extends O {
-  override def toString = "" + lit
-}
-
-sealed abstract class P
-case class PUri(u:Uri) extends P {
-  override def toString = "" + u
-}
-case class PVar(v:Var) extends P {
-  override def toString = "" + v
-}
-
 case class Literal(lit:RDFLiteral) {
   override def toString = "" + lit
 }
@@ -86,10 +59,16 @@
 case class PrimaryExpressionLt(left:SparqlTermExpression, right:SparqlTermExpression) extends PrimaryExpression
 case class SparqlTermExpression(term:Term)
 
-sealed abstract class Term
-case class TermUri(u:Uri) extends Term
-case class TermVar(v:Var) extends Term
-case class TermLit(lit:Literal) extends Term
+sealed trait Term
+case class TermUri(u:Uri) extends Term {
+  override def toString = u.toString
+}
+case class TermVar(v:Var) extends Term {
+  override def toString = v.toString
+}
+case class TermLit(lit:Literal) extends Term {
+  override def toString = lit.toString
+}
 
 
 case class Sparql() extends JavaTokenParsers {
@@ -184,18 +163,20 @@
   def triplepattern:Parser[TriplePattern] =
     subject ~ predicate ~ objectt ^^ { case s~p~o => TriplePattern(s, p, o) }
 
-  def subject:Parser[S] = (
-      qnameORuri ^^ { case x => SUri(x) }
-    | varr ^^ { x => SVar(x) }
+  def subject:Parser[Term] = (
+      qnameORuri ^^ { case x => TermUri(x) }
+    | varr ^^ { x => TermVar(x) }
   )
 
-  def predicate:Parser[P] =
-    qnameORuri ^^ { x => PUri(x) }
+  def predicate:Parser[Term] = (
+      qnameORuri ^^ { x => TermUri(x) }
+    | varr ^^ { x => TermVar(x) }
+  )
 
-  def objectt:Parser[O] = (
-      qnameORuri ^^ { case x => OUri(x) }
-    | varr ^^ { x => OVar(x) }
-    | literal ^^ { x => OLit(x) }
+  def objectt:Parser[Term] = (
+      qnameORuri ^^ { case x => TermUri(x) }
+    | varr ^^ { x => TermVar(x) }
+    | literal ^^ { x => TermLit(x) }
   )
 
   def qnameORuri:Parser[Uri] = (
--- a/src/main/scala/SparqlToSparql.scala	Mon Feb 01 09:15:57 2010 -0500
+++ b/src/main/scala/SparqlToSparql.scala	Mon Feb 08 09:52:01 2010 -0500
@@ -10,35 +10,19 @@
 import w3c.sw.sparql
 
 object SparqlToSparql {
-  def substituteTerm (changeMe:sparql.S, from:sparql.Term, to:sparql.Term):sparql.S = {
-    if (toTerm(changeMe) == from) to match {
-      case sparql.TermUri(u) => sparql.SUri(u)
-      case sparql.TermVar(v) => sparql.SVar(v)
-      case sparql.TermLit(l) => error("literal subject \"" + l + "\" not allowed in SPARQL")
-    }
-    else changeMe
+  var RuleLabels = scala.collection.mutable.Map[String,String]()
+  var Abbreviations = scala.collection.mutable.Map[String,String]()
+  def _shorten (s:String) = {
+    val s2 = if (RuleLabels.contains(s)) RuleLabels(s)
+	     else s
+    val s3 = Abbreviations.foldLeft(s2)((s, ss) => s.replace(ss._1, ss._2))
+    s3
   }
-  def substituteTerm (changeMe:sparql.O, from:sparql.Term, to:sparql.Term):sparql.O = {
-    if (toTerm(changeMe) == from) to match {
-      case sparql.TermUri(u) => sparql.OUri(u)
-      case sparql.TermVar(v) => sparql.OVar(v)
-      case sparql.TermLit(l) => sparql.OLit(l)
-    }
+
+  def substituteTerm (changeMe:sparql.Term, from:sparql.Term, to:sparql.Term):sparql.Term = {
+    if (changeMe == from) to
     else changeMe
   }
-  def toTerm (term:sparql.S):sparql.Term = {
-    term match {
-      case sparql.SUri(u) => sparql.TermUri(u)
-      case sparql.SVar(v) => sparql.TermVar(v)
-    }
-  }
-  def toTerm (term:sparql.O):sparql.Term = {
-    term match {
-      case sparql.OUri(u) => sparql.TermUri(u)
-      case sparql.OVar(v) => sparql.TermVar(v)
-      case sparql.OLit(l) => sparql.TermLit(l)
-    }
-  }
   def substitute (gp:sparql.GraphPattern, from:sparql.Term, to:sparql.Term) = {
     gp match {
       case sparql.TriplesBlock(triplepatterns) => sparql.TriplesBlock(
@@ -53,49 +37,151 @@
       case _ => error("not implemented" + gp)
     }
   }
-  case class HornRule (head:sparql.TriplePattern, gp:sparql.GraphPattern) {
-    override def toString = "{" + head + "} => {" + gp + "}"
+  def substituteGraphPattern (gp:sparql.GraphPattern, vartermmap:Map[sparql.Var, sparql.Term]):sparql.GraphPattern = {
+    vartermmap.foldLeft(gp)((incrementalGP, varterm) => {
+      val (varr, term) = varterm
+      substitute(incrementalGP, sparql.TermVar(varr), term)
+    })
+  }
+  case class HornRule (trigger:sparql.TriplePattern, construct:sparql.Construct) {
+    override def toString = "{ \"" + trigger + "\" } => {\"\n  " + _shorten(construct.gp.toString).replace("\n", "\n  ") + "\n\"}"
     def transform (tp:sparql.TriplePattern):sparql.GraphPattern = {
-      substitute(substitute(gp, toTerm(head.s), toTerm(tp.s)), toTerm(head.o), toTerm(tp.o))
+      substitute(substitute(construct.gp, trigger.s, tp.s), trigger.o, tp.o)
     }
   }
-  case class RuleMap (rules:Map[sparql.Uri, HornRule]) {
-    def transform (tp:sparql.TriplePattern):sparql.GraphPattern = {
-      tp.p match {
-	case sparql.PUri(u) =>
-	  try { rules(u).transform(tp) } catch {
-	    case e:java.util.NoSuchElementException => sparql.TriplesBlock(List(tp))
+  case class Bindings (b:Map[sparql.Construct, List[Map[sparql.Var, sparql.Term]]]) {
+    def toGraphPattern ():sparql.GraphPattern = {
+      val conjuncts = b.foldLeft(List[sparql.GraphPattern]())((conj, constructlist) => {
+	val (construct, l) = constructlist
+	l.map((vartermmap) => substituteGraphPattern(construct.gp, vartermmap))
+      })
+      if (conjuncts.size == 0)
+	sparql.TriplesBlock(List[sparql.TriplePattern]())
+      else if (conjuncts.size > 1)
+	sparql.TableConjunction(conjuncts)
+      else
+	conjuncts(0)
+    }
+    override def toString = "Bindings(Map(" + b.map((constructlist) => {
+      val (construct, l) = constructlist
+      "\"" + _shorten(construct.head.toString) + "\" -> List(" + l.map((vartermmap) => {
+	"Map(" + vartermmap.map((varterm) => {
+	  val (varr, term) = varterm
+	  varr.toString + ":" + term.toString
+	}) + ")"
+      }).mkString("\n    ", ",\n    ", "") + ")"
+    }).mkString("\n  ", ",\n  ", "") + "))"
+    def ensureGraphPattern (construct:sparql.Construct) = {
+      if (b.contains(construct)) this
+      else Bindings(b + (construct -> List[Map[sparql.Var, sparql.Term]]()))
+    }
+    // val varsS:Option[Bindings] = vars.maybeRebind(construct, v, to)
+    def maybeBind (construct:sparql.Construct, v:sparql.Term, to:sparql.Term):Option[Bindings] = {
+      v match {
+	case v:sparql.TermVar =>
+	  if (b(construct).size > 0 && b(construct)(0).contains(v.v)) {
+	    println(v.v + ":" + b(construct)(0)(v.v) + " == " + to + " => " + (to == b(construct)(0)(v.v)))
+	    if (to == b(construct)(0)(v.v)) Some(this) // !!! iterate on 0
+	    else None
+	  } else {
+	    val old = if (b(construct).size > 0) b(construct)(0)
+		      else Map[sparql.Var, sparql.Term]()
+	    println(v.v + " unbound in " + old)
+	    val m:Map[sparql.Var, sparql.Term] = old ++ Map(v.v -> to)
+	    Some(Bindings(b + (construct -> List(m))))
 	  }
-	case _ => error("not implemented: " + tp.p)
+	case u:sparql.TermUri =>
+	  if (to == u.u) Some(this)
+	  else None
+	case l:sparql.TermLit =>
+	  if (to == l.lit) Some(this)
+	  else None
       }
     }
   }
+  def createEmptyBindings () = Bindings(Map[sparql.Construct, List[Map[sparql.Var, sparql.Term]]]())
+
+  case class RuleMap (rules:Map[sparql.Uri, List[HornRule]]) {
+    override def toString = "RuleMap(Map(" + rules.map((ent) => {
+      val (u, l) = ent
+      "\"" + _shorten(u.toString) + "\" -> List(" + l.map((hr) => {
+	_shorten(hr.toString).replace("\n", "\n    ")
+      }).mkString("\n    ", ",\n    ", "") + ")"
+    }).mkString("\n  ", ",\n  ", "") + "))"
+
+    def transform (prove:List[sparql.TriplePattern], used:Set[sparql.TriplePattern], varsP:Bindings):Bindings = {
+      val _pad = used.foldLeft("")((s, x) => s + " ")
+      def _deepPrint (s:String):Unit = { println(used.size + ":" + _pad + s.replace("\n", "\n" + _pad)) }
+      def _deepPrint1 (prefix:String, s:String):Unit = {
+	val p = used.size + ":" + prefix + _pad
+	println(p + s.replace("\n", "\n" + p))
+      }
+
+      val car = prove(0)
+      val cdr = prove.filterNot (_ == car)
+      _deepPrint("RuleMap.transform(" + _shorten(car.toString) + ", " + varsP.toString + ")")
+      val ret = car.p match {
+	case sparql.TermUri(u) =>
+	  // for each rule that supplies predicate u
+	  var _ruleNo = 0;
+	  rules(u).foldLeft(createEmptyBindings)((bindings, hornRule) => {
+	    val _prefix = "rule:" + _ruleNo
+	    _ruleNo = _ruleNo + 1
+	    _deepPrint1(_prefix, "trying " + _shorten(hornRule.trigger.toString))
+	    val vars = varsP.ensureGraphPattern(hornRule.construct)
+	    // try matching the subject
+	    val varsS:Option[Bindings] = vars.maybeBind(hornRule.construct, hornRule.trigger.s, car.s)
+	    val ret:Bindings = if (varsS.isDefined) {
+	      // try matching the object
+	      val varsO:Option[Bindings] = varsS.get.maybeBind(hornRule.construct, hornRule.trigger.o, car.o)
+	      if (varsO.isDefined) {
+		if (cdr.size > 0) {
+		  transform(cdr, used + car, varsO.get)
+		} else {
+		  _deepPrint1("match!", _shorten(hornRule.trigger.toString) + "(" + _shorten(car.toString) + ") matches with " + _shorten(varsO.get.toString))
+		  varsO.get
+		}
+	      } else createEmptyBindings
+	    } else createEmptyBindings
+	    _deepPrint1(_prefix, _shorten(hornRule.trigger.toString) + "(" + _shorten(car.toString) + ") matches ..." + bindings.toString + ret.toString)
+	    if (ret.b.size > bindings.b.size) ret
+	    else bindings
+	  })
+	case _ => error("not implemented: " + car.p)
+      }
+      _deepPrint("RuleMap.transform(" + _shorten(car.toString) + ") => " + _shorten(ret.toString))
+      ret
+    }
+  }
 
   def mapGraphPattern (gp:sparql.GraphPattern, ruleMap:RuleMap):sparql.GraphPattern = {
     gp match {
       case sparql.TriplesBlock(tps) => {
-	val l = tps.foldLeft(List[sparql.GraphPattern]())((s, tp) => s ++ Set(ruleMap.transform(tp)))
-	if (l.size > 1)
-	  sparql.TableConjunction(l)
-	else
-	  l(0)
+	val emptyBindings = createEmptyBindings
+	ruleMap.transform(tps, Set[sparql.TriplePattern](), emptyBindings).toGraphPattern
       }
       case _ => error("not implemented: " + gp);
     }
   }
 
   def apply (query:sparql.Select, constructs:List[sparql.Construct]) : sparql.Select = {
+    var _ruleNo = 0
     val ruleMap = RuleMap({
-      constructs.foldLeft(Map[sparql.Uri, HornRule]())((m, rule) => {
+      constructs.foldLeft(Map[sparql.Uri, List[HornRule]]())((m, rule) => {
+	RuleLabels.update(rule.head.toString, "head" + _ruleNo)
+	RuleLabels.update(rule.gp.toString, "body" + _ruleNo)
+	_ruleNo = _ruleNo + 1
 	rule.head.triplepatterns.foldLeft(m)((m, tp) => m + ({
 	  tp.p match {
-	    case sparql.PUri(u) => u -> HornRule(tp, rule.gp)
+	    case sparql.TermUri(u) => u -> {
+	      if (m.contains(u)) m(u) ++ List(HornRule(tp, rule))
+	      else List(HornRule(tp, rule))}
 	    case _ => error("not implemented: " + tp.p)
 	  }
 	}))
       })
     })
-    // println("ruleMap: " + ruleMap)
+    println("ruleMap: " + ruleMap)
     sparql.Select(
       query.attrs,
       mapGraphPattern(query.gp, ruleMap)
--- a/src/main/scala/SparqlToSql.scala	Mon Feb 01 09:15:57 2010 -0500
+++ b/src/main/scala/SparqlToSql.scala	Mon Feb 08 09:52:01 2010 -0500
@@ -114,18 +114,11 @@
 Sparql.parseObjectURI(
 Sparql.parsePredicateURI(
 */
-  def relVarFromS(s:sparql.S):sql.RelVar = {
+  def relVarFromTerm(s:sparql.Term):sql.RelVar = {
     s match {
-      case sparql.SUri(ob) => relVarFromNode(ob)
-      case sparql.SVar(v) => relVarFromVar(v)
-    }
-  }
-
-  def relVarFromO(o:sparql.O):sql.RelVar = {
-    o match {
-      case sparql.OUri(ob) => relVarFromNode(ob)
-      case sparql.OVar(v) => relVarFromVar(v)
-      case sparql.OLit(l) => relVarFromLiteral(l)
+      case sparql.TermUri(ob) => relVarFromNode(ob)
+      case sparql.TermVar(v)  => relVarFromVar(v)
+      case sparql.TermLit(l)  => relVarFromLiteral(l)
     }
   }
 
@@ -236,19 +229,20 @@
   def bindOnPredicate(db:sql.DatabaseDesc, stateP:R2RState, triple:sparql.TriplePattern, enforceForeignKeys:Boolean):R2RState = {
     val sparql.TriplePattern(s, p, o) = triple
     p match {
-      case sparql.PVar(v) => error("variable predicates require tedious enumeration; too tedious for me.")
-      case sparql.PUri(uri) => {
+      case sparql.TermVar(v) => error("variable predicates require tedious enumeration; too tedious for me.")
+      case sparql.TermUri(uri) => {
 	val PUri(stem, spRel, spAttr) = parsePredicateURI(uri)
 	/* Attributes that come from the predicate: */
 	val rel = sql.Relation(sql.Name(spRel.s))
 	val attr = sql.Attribute(sql.Name(spAttr.s))
-	val relvar = relVarFromS(s)
+	val relvar = relVarFromTerm(s)
 
 	/* Attributes that come from the subject: */
 	val objattr = sql.RelVarAttr(relvar, attr)
 	val state_postSubj = s match {
-	  case sparql.SUri(u) => uriConstraint(stateP, sql.RelVarAttr(relvar, db.relationdescs(rel).primarykey.get), parseObjectURI(u), true)
-	  case sparql.SVar(v) => varConstraint(stateP, relvar, db.relationdescs(rel).primarykey, v, db, rel)
+	  case sparql.TermUri(u) => uriConstraint(stateP, sql.RelVarAttr(relvar, db.relationdescs(rel).primarykey.get), parseObjectURI(u), true)
+	  case sparql.TermVar(v) => varConstraint(stateP, relvar, db.relationdescs(rel).primarykey, v, db, rel)
+	  case _                 => error("illegal SPARQL subject: " + s)
 	}
 	val state_subjJoin = R2RState(state_postSubj.joins + sql.InnerJoin(sql.AliasedResource(rel,relvar), None), state_postSubj.varmap, state_postSubj.exprs)
 
@@ -269,7 +263,7 @@
 	      case sql.Value(x) => x
 	    }
 	    if (enforceForeignKeys) {
-	      val oRelVar = relVarFromO(o)
+	      val oRelVar = relVarFromTerm(o)
 	      val fkaliasattr = sql.RelVarAttr(oRelVar, fkattr)
 	      val state_t = R2RState(state_subjJoin.joins + sql.InnerJoin(sql.AliasedResource(fkrel,oRelVar), None),
 				     state_subjJoin.varmap,
@@ -284,23 +278,24 @@
 	  case sql.Value(dt) => (objattr, rel, dt, state_subjJoin)
 	}
 	o match {
-	  case sparql.OLit(l) => literalConstraint(state_fkeys, targetattr, l, dt)
-	  case sparql.OUri(u) => uriConstraint    (state_fkeys, targetattr, parseObjectURI(u), enforceForeignKeys)
-	  case sparql.OVar(v) => varConstraint    (state_fkeys, targetattr.relvar, Some(targetattr.attribute), v, db, targetrel)
+	  case sparql.TermLit(l) => literalConstraint(state_fkeys, targetattr, l, dt)
+	  case sparql.TermUri(u) => uriConstraint    (state_fkeys, targetattr, parseObjectURI(u), enforceForeignKeys)
+	  case sparql.TermVar(v) => varConstraint    (state_fkeys, targetattr.relvar, Some(targetattr.attribute), v, db, targetrel)
 	}
       }
+      case _                  => error("illegal SPARQL predicate: " + p)
     }
   }
 
   def findVars(triple:sparql.TriplePattern):Set[sparql.Var] = {
     val sparql.TriplePattern(s, p, o) = triple
     val varS:Set[sparql.Var] = s match {
-      case sparql.SVar(v) => Set(v)
-      case _              => Set()
+      case sparql.TermVar(v) => Set(v)
+      case _                 => Set()
     }
     val varO:Set[sparql.Var] = o match {
-      case sparql.OVar(v) => Set(v)
-      case _              => Set()
+      case sparql.TermVar(v) => Set(v)
+      case _                 => Set()
     }
     varS ++ varO
   }
--- a/src/test/scala/SparqlTest.scala	Mon Feb 01 09:15:57 2010 -0500
+++ b/src/test/scala/SparqlTest.scala	Mon Feb 08 09:52:01 2010 -0500
@@ -11,7 +11,7 @@
     val e = """
 ?emp      <http://hr.example/DB/Employee#lastName>   "bob"^^<http://www.w3.org/2001/XMLSchema#string>
 """
-    val expected = TriplesBlock(List(TriplePattern(SVar(Var("emp")),PUri(Uri("http://hr.example/DB/Employee#lastName")),OLit(Literal(RDFLiteral("bob",Datatype(new URI("http://www.w3.org/2001/XMLSchema#string"))))))))
+    val expected = TriplesBlock(List(TriplePattern(TermVar(Var("emp")),TermUri(Uri("http://hr.example/DB/Employee#lastName")),TermLit(Literal(RDFLiteral("bob",Datatype(new URI("http://www.w3.org/2001/XMLSchema#string"))))))))
     assert(expected === (a.parseAll(a.triplesblock, e).get))
   }
 
@@ -20,7 +20,7 @@
     val e = """
 ?emp      <http://hr.example/DB/Employee#age>   "21"^^<http://www.w3.org/2001/XMLSchema#integer>
 """
-    val expected = TriplesBlock(List(TriplePattern(SVar(Var("emp")),PUri(Uri("http://hr.example/DB/Employee#age")),OLit(Literal(RDFLiteral("21",Datatype(new URI("http://www.w3.org/2001/XMLSchema#integer"))))))))
+    val expected = TriplesBlock(List(TriplePattern(TermVar(Var("emp")),TermUri(Uri("http://hr.example/DB/Employee#age")),TermLit(Literal(RDFLiteral("21",Datatype(new URI("http://www.w3.org/2001/XMLSchema#integer"))))))))
     assert(expected === (a.parseAll(a.triplesblock, e).get))
   }
 
@@ -35,17 +35,17 @@
       TriplesBlock(
 	List(
 	  TriplePattern(
-	    SVar(Var("emp")),
-	    PUri(Uri("http://hr.example/DB/Employee#lastName")),
-	    OVar(Var("empName"))),
+	    TermVar(Var("emp")),
+	    TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+	    TermVar(Var("empName"))),
 	  TriplePattern(
-	    SVar(Var("emp")),
-	    PUri(Uri("http://hr.example/DB/Employee#manager")),
-	    OVar(Var("manager"))),
+	    TermVar(Var("emp")),
+	    TermUri(Uri("http://hr.example/DB/Employee#manager")),
+	    TermVar(Var("manager"))),
 	  TriplePattern(
-	    SVar(Var("manager")),
-	    PUri(Uri("http://hr.example/DB/Employee#lastName")),
-	    OVar(Var("managName")))))
+	    TermVar(Var("manager")),
+	    TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+	    TermVar(Var("managName")))))
     assert(tps === a.parseAll(a.triplesblock, e).get)
   }
 
@@ -104,9 +104,9 @@
 	TriplesBlock(
 	  List(
 	    TriplePattern(
-	      SVar(Var("emp")),
-		PUri(Uri("http://hr.example/DB/Employee#lastName")),
-	      OVar(Var("empName"))))))
+	      TermVar(Var("emp")),
+		TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+	      TermVar(Var("empName"))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
@@ -125,9 +125,9 @@
 	TriplesBlock(
 	  List(
 	    TriplePattern(
-	      SVar(Var("emp")),
-		PUri(Uri("http://hr.example/DB/Employee#lastName")),
-	      OVar(Var("empName"))))))
+	      TermVar(Var("emp")),
+		TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+	      TermVar(Var("empName"))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
@@ -146,9 +146,9 @@
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
-		SVar(Var("emp")),
-		PUri(Uri("http://hr.example/DB/Employee#lastName")),
-		OVar(Var("empName"))))),
+		TermVar(Var("emp")),
+		TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+		TermVar(Var("empName"))))),
 	  Expression(List(
 	    PrimaryExpressionLt(SparqlTermExpression(TermVar(Var("manBday"))),
 				      SparqlTermExpression(TermVar(Var("empBday")))), 
@@ -172,17 +172,17 @@
 	TriplesBlock(
 	  List(
 	    TriplePattern(
-	      SVar(Var("emp")),
-		PUri(Uri("http://hr.example/DB/Employee#lastName")),
-	      OVar(Var("empName"))),
+	      TermVar(Var("emp")),
+		TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+	      TermVar(Var("empName"))),
 	    TriplePattern(
-	      SVar(Var("emp")),
-	      PUri(Uri("http://hr.example/DB/Employee#manager")),
-	      OVar(Var("manager"))),
+	      TermVar(Var("emp")),
+	      TermUri(Uri("http://hr.example/DB/Employee#manager")),
+	      TermVar(Var("manager"))),
 	    TriplePattern(
-	      SVar(Var("manager")),
-	      PUri(Uri("http://hr.example/DB/Employee#lastName")),
-	      OVar(Var("managName"))))))
+	      TermVar(Var("manager")),
+	      TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+	      TermVar(Var("managName"))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
@@ -218,9 +218,9 @@
 	TriplesBlock(
 	  List(
 	    TriplePattern(
-	      SVar(Var("x")),
-	      PUri(Uri("http://hr.example/DB/Employee#manager")),
-	      OVar(Var("y"))))))
+	      TermVar(Var("x")),
+	      TermUri(Uri("http://hr.example/DB/Employee#manager")),
+	      TermVar(Var("y"))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
@@ -236,15 +236,15 @@
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
-		SVar(Var("x")),
-		PUri(Uri("http://hr.example/DB/Employee#manager")),
-		OVar(Var("y"))))),
+		TermVar(Var("x")),
+		TermUri(Uri("http://hr.example/DB/Employee#manager")),
+		TermVar(Var("y"))))),
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
-		SVar(Var("x")),
-		PUri(Uri("http://hr.example/DB/Employee#manager")),
-		OVar(Var("y"))))))))
+		TermVar(Var("x")),
+		TermUri(Uri("http://hr.example/DB/Employee#manager")),
+		TermVar(Var("y"))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
@@ -260,15 +260,15 @@
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
-		SVar(Var("x")),
-		PUri(Uri("http://hr.example/DB/Employee#manager")),
-		OVar(Var("y"))))),
+		TermVar(Var("x")),
+		TermUri(Uri("http://hr.example/DB/Employee#manager")),
+		TermVar(Var("y"))))),
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
-		SVar(Var("x")),
-		PUri(Uri("http://hr.example/DB/Employee#manager")),
-		OVar(Var("y"))))))))
+		TermVar(Var("x")),
+		TermUri(Uri("http://hr.example/DB/Employee#manager")),
+		TermVar(Var("y"))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
@@ -284,16 +284,16 @@
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
-		SVar(Var("x")),
-		PUri(Uri("http://hr.example/DB/Employee#manager")),
-		OVar(Var("y"))))),
+		TermVar(Var("x")),
+		TermUri(Uri("http://hr.example/DB/Employee#manager")),
+		TermVar(Var("y"))))),
 	  OptionalGraphPattern(
 	    TriplesBlock(
 	      List(
 		TriplePattern(
-		  SVar(Var("x")),
-		  PUri(Uri("http://hr.example/DB/Employee#manager")),
-		  OVar(Var("y")))))))))
+		  TermVar(Var("x")),
+		  TermUri(Uri("http://hr.example/DB/Employee#manager")),
+		  TermVar(Var("y")))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
@@ -309,9 +309,9 @@
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
-		SVar(Var("x")),
-		PUri(Uri("http://hr.example/DB/Employee#manager")),
-		OVar(Var("y")))))))
+		TermVar(Var("x")),
+		TermUri(Uri("http://hr.example/DB/Employee#manager")),
+		TermVar(Var("y")))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
@@ -327,16 +327,16 @@
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
-		SVar(Var("x")),
-		PUri(Uri("http://hr.example/DB/Employee#manager")),
-		OVar(Var("y"))))),
+		TermVar(Var("x")),
+		TermUri(Uri("http://hr.example/DB/Employee#manager")),
+		TermVar(Var("y"))))),
 	  MinusGraphPattern(
 	    TriplesBlock(
 	      List(
 		TriplePattern(
-		  SVar(Var("x")),
-		  PUri(Uri("http://hr.example/DB/Employee#manager")),
-		  OVar(Var("y")))))))))
+		  TermVar(Var("x")),
+		  TermUri(Uri("http://hr.example/DB/Employee#manager")),
+		  TermVar(Var("y")))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
@@ -360,39 +360,39 @@
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
-		SVar(Var("who")),
-		PUri(Uri("http://hr.example/DB/Employee#lastName")),
-		OLit(Literal(RDFLiteral("Smith",Datatype(new URI("http://www.w3.org/2001/XMLSchema#string")))))))),
+		TermVar(Var("who")),
+		TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+		TermLit(Literal(RDFLiteral("Smith",Datatype(new URI("http://www.w3.org/2001/XMLSchema#string")))))))),
 	  TableDisjunction(List(
 	    TriplesBlock(
 	      List(
 		TriplePattern(
-		  SVar(Var("above")),
-		  PUri(Uri("http://hr.example/DB/Manage#manages")),
-		  OVar(Var("who"))),
+		  TermVar(Var("above")),
+		  TermUri(Uri("http://hr.example/DB/Manage#manages")),
+		  TermVar(Var("who"))),
 		TriplePattern(
-		  SVar(Var("above")),
-		  PUri(Uri("http://hr.example/DB/Manage#manager")),
-		  OVar(Var("manager"))),
+		  TermVar(Var("above")),
+		  TermUri(Uri("http://hr.example/DB/Manage#manager")),
+		  TermVar(Var("manager"))),
 		TriplePattern(
-		  SVar(Var("manager")),
-		  PUri(Uri("http://hr.example/DB/Employee#lastName")),
-		  OVar(Var("name")))
+		  TermVar(Var("manager")),
+		  TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+		  TermVar(Var("name")))
 	      )),
 	    TriplesBlock(
 	      List(
 		TriplePattern(
-		  SVar(Var("below")),
-		  PUri(Uri("http://hr.example/DB/Manage#manager")),
-		  OVar(Var("who"))),
+		  TermVar(Var("below")),
+		  TermUri(Uri("http://hr.example/DB/Manage#manager")),
+		  TermVar(Var("who"))),
 		TriplePattern(
-		  SVar(Var("below")),
-		  PUri(Uri("http://hr.example/DB/Manage#manages")),
-		  OVar(Var("managed"))),
+		  TermVar(Var("below")),
+		  TermUri(Uri("http://hr.example/DB/Manage#manages")),
+		  TermVar(Var("managed"))),
 		TriplePattern(
-		  SVar(Var("managed")),
-		  PUri(Uri("http://hr.example/DB/Employee#lastName")),
-		  OVar(Var("name")))
+		  TermVar(Var("managed")),
+		  TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+		  TermVar(Var("name")))
 	      )))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -412,11 +412,11 @@
 """
     val tps =
       Select(SparqlAttributeList(List(Var("emp1Name"), Var("emp2Name"), Var("emp3Name"))),
-       TableFilter(TableConjunction(List(TriplesBlock(List(TriplePattern(SVar(Var("emp1")), PUri(Uri("http://hr.example/DB/Employee#lastName")), OVar(Var("emp1Name"))))),
-					 OptionalGraphPattern(TriplesBlock(List(TriplePattern(SVar(Var("emp1")), PUri(Uri("http://hr.example/DB/Employee#birthday")), OVar(Var("birthday")))))),
-					 TriplesBlock(List(TriplePattern(SVar(Var("emp2")), PUri(Uri("http://hr.example/DB/Employee#lastName")), OVar(Var("emp2Name"))))),
-					 OptionalGraphPattern(TriplesBlock(List(TriplePattern(SVar(Var("emp2")), PUri(Uri("http://hr.example/DB/Employee#birthday")), OVar(Var("birthday")))))),
-					 TriplesBlock(List(TriplePattern(SVar(Var("emp4")),PUri(Uri("http://hr.example/DB/Employee#birthday")),OVar(Var("birthday"))))))),
+       TableFilter(TableConjunction(List(TriplesBlock(List(TriplePattern(TermVar(Var("emp1")), TermUri(Uri("http://hr.example/DB/Employee#lastName")), TermVar(Var("emp1Name"))))),
+					 OptionalGraphPattern(TriplesBlock(List(TriplePattern(TermVar(Var("emp1")), TermUri(Uri("http://hr.example/DB/Employee#birthday")), TermVar(Var("birthday")))))),
+					 TriplesBlock(List(TriplePattern(TermVar(Var("emp2")), TermUri(Uri("http://hr.example/DB/Employee#lastName")), TermVar(Var("emp2Name"))))),
+					 OptionalGraphPattern(TriplesBlock(List(TriplePattern(TermVar(Var("emp2")), TermUri(Uri("http://hr.example/DB/Employee#birthday")), TermVar(Var("birthday")))))),
+					 TriplesBlock(List(TriplePattern(TermVar(Var("emp4")),TermUri(Uri("http://hr.example/DB/Employee#birthday")),TermVar(Var("birthday"))))))),
 		   Expression(List(PrimaryExpressionLt(SparqlTermExpression(TermVar(Var("emp1Name"))),SparqlTermExpression(TermVar(Var("emp2Name")))), PrimaryExpressionLt(SparqlTermExpression(TermVar(Var("emp2Name"))),SparqlTermExpression(TermVar(Var("emp3Name")))), PrimaryExpressionLt(SparqlTermExpression(TermVar(Var("emp3Name"))),SparqlTermExpression(TermVar(Var("emp4Name"))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -434,15 +434,15 @@
 	TriplesBlock(
 	  List(
 	    TriplePattern(
-	      SVar(Var("emp")),
-	      PUri(Uri("http://xmlns.com/foaf/0.1/last_name")),
-	      OVar(Var("empName"))))),
+	      TermVar(Var("emp")),
+	      TermUri(Uri("http://xmlns.com/foaf/0.1/last_name")),
+	      TermVar(Var("empName"))))),
 	TriplesBlock(
 	  List(
 	    TriplePattern(
-	      SVar(Var("emp")),
-	      PUri(Uri("http://hr.example/DB/Employee#lastName")),
-	      OVar(Var("empName"))))))
+	      TermVar(Var("emp")),
+	      TermUri(Uri("http://hr.example/DB/Employee#lastName")),
+	      TermVar(Var("empName"))))))
     assert(tps === a.parseAll(a.construct, e).get)
   }
 
--- a/src/test/scala/SparqlToSparqlTest.scala	Mon Feb 01 09:15:57 2010 -0500
+++ b/src/test/scala/SparqlToSparqlTest.scala	Mon Feb 08 09:52:01 2010 -0500
@@ -14,23 +14,23 @@
  */
 class SparqlToSparqlTest extends FunSuite {
 
-  test("cat") {
-    val sparqlParser = Sparql()
-    val query = sparqlParser.parseAll(sparqlParser.select, """
-PREFIX empP : <http://hr.example/DB/Employee#>
-SELECT ?emp {
-?emp  empP:manager    <http://hr.example/DB/Employee/empid.18#record>
-}
-""").get
-    val transformed = SparqlToSparql(query, List[sparql.Construct]())
-    val expected = sparqlParser.parseAll(sparqlParser.select, """
-PREFIX empP : <http://hr.example/DB/Employee#>
-SELECT ?emp {
-?emp  empP:manager    <http://hr.example/DB/Employee/empid.18#record>
-}
-""").get
-    assert(transformed === expected)
-  }
+//   test("cat") {
+//     val sparqlParser = Sparql()
+//     val query = sparqlParser.parseAll(sparqlParser.select, """
+// PREFIX empP : <http://hr.example/DB/Employee#>
+// SELECT ?emp {
+// ?emp  empP:manager    <http://hr.example/DB/Employee/empid.18#record>
+// }
+// """).get
+//     val transformed = SparqlToSparql(query, List[sparql.Construct]())
+//     val expected = sparqlParser.parseAll(sparqlParser.select, """
+// PREFIX empP : <http://hr.example/DB/Employee#>
+// SELECT ?emp {
+// ?emp  empP:manager    <http://hr.example/DB/Employee/empid.18#record>
+// }
+// """).get
+//     assert(transformed === expected)
+//   }
 
   test("foaf:last_name single") {
     val sparqlParser = Sparql()
@@ -93,40 +93,47 @@
     assert(transformed === expected)
   }
 
-//   test("to many-to-many") {
-//     val sparqlParser = Sparql()
-//     val query = sparqlParser.parseAll(sparqlParser.select, """
-// PREFIX foaf : <http://xmlns.com/foaf/0.1/>
-// PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
-// SELECT ?lname {
-//   ?who  foaf:last_name    ?lname .
-//   ?who  foaf:knows        ?whom  .
-//   ?whom foaf:last_name    "Smith"^^xsd:string }
-// """).get
-//     val rule1 = sparqlParser.parseAll(sparqlParser.construct, """
-// PREFIX foaf : <http://xmlns.com/foaf/0.1/>
-// PREFIX empP : <http://hr.example/DB/Employee#>
-// PREFIX task : <http://hr.example/DB/Task#>
-// CONSTRUCT { ?emp  foaf:last_name  ?wname .
-//             ?emp  foaf:knows      ?man .
-//             ?man  foaf:last_name  ?mname }
-//     WHERE { ?emp  empP:lastName   ?wname .
-//             ?pair task:drone      ?emp .
-//             ?pair task:manager    ?man .
-//             ?man  empP:lastName   ?mname }
-// """).get
-//     val transformed = SparqlToSparql(query, List(rule1))
-//     val expected = sparqlParser.parseAll(sparqlParser.select, """
-// PREFIX empP : <http://hr.example/DB/Employee#>
-// PREFIX task : <http://hr.example/DB/Task#>
-// PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
-// SELECT ?lname
-//      { ?who  empP:lastName   ?lname .
-//        ?pair task:drone      ?who .
-//        ?pair task:manager    ?whom .
-//        ?whom empP:lastName   "Smith"^^xsd:string }
-// """).get
-//     assert(transformed === expected)
-//   }
+  test("to many-to-many") {
+    val sparqlParser = Sparql()
+    val query = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX foaf : <http://xmlns.com/foaf/0.1/>
+PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
+SELECT ?lname {
+  ?who  foaf:last_name    ?lname .
+  ?who  foaf:knows        ?whom  .
+  ?whom foaf:last_name    "Smith"^^xsd:string }
+""").get
+    val rule1 = sparqlParser.parseAll(sparqlParser.construct, """
+PREFIX foaf : <http://xmlns.com/foaf/0.1/>
+PREFIX empP : <http://hr.example/DB/Employee#>
+PREFIX task : <http://hr.example/DB/Task#>
+CONSTRUCT { ?emp  foaf:last_name  ?wname .
+            ?emp  foaf:knows      ?man .
+            ?man  foaf:last_name  ?mname }
+    WHERE { ?emp  empP:lastName   ?wname .
+            ?pair task:drone      ?emp .
+            ?pair task:manager    ?man .
+            ?man  empP:lastName   ?mname }
+""").get
+    SparqlToSparql.Abbreviations.update("<http://xmlns.com/foaf/0.1/last_name>", "foaf:last_name")
+    SparqlToSparql.Abbreviations.update("<http://xmlns.com/foaf/0.1/knows>", "foaf:knows")
+    SparqlToSparql.Abbreviations.update("<http://hr.example/DB/Employee#lastName>", "Employee:lastName")
+    SparqlToSparql.Abbreviations.update("<http://hr.example/DB/Task#drone>", "Task:drone")
+    SparqlToSparql.Abbreviations.update("<http://hr.example/DB/Task#manager>", "Task:manager")
+    SparqlToSparql.Abbreviations.update("^^http://www.w3.org/2001/XMLSchema#string", "")
+
+    val transformed = SparqlToSparql(query, List(rule1))
+    val expected = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX empP : <http://hr.example/DB/Employee#>
+PREFIX task : <http://hr.example/DB/Task#>
+PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
+SELECT ?lname
+     { ?who  empP:lastName   ?lname .
+       ?pair task:drone      ?who .
+       ?pair task:manager    ?whom .
+       ?whom empP:lastName   "Smith"^^xsd:string }
+""").get
+    assert(transformed === expected)
+  }
 
 }