~ finally managed to deal with the isomorphic pattern and type unification \o/
authorAlexandre Bertails <bertails@w3.org>
Fri, 07 Jan 2011 19:20:00 -0500
changeset 298 61062fd31429
parent 297 489486b97905
child 299 6dea4729cef8
~ finally managed to deal with the isomorphic pattern and type unification \o/
directmapping/src/main/scala/DirectMapping.scala
directmapping/src/test/scala/DirectMappingTest.scala
rdf/src/main/scala/RDF.scala
turtle/src/main/scala/turtle.scala
turtle/src/test/scala/turtleTest.scala
--- a/directmapping/src/main/scala/DirectMapping.scala	Fri Jan 07 12:50:06 2011 -0500
+++ b/directmapping/src/main/scala/DirectMapping.scala	Fri Jan 07 19:20:00 2011 -0500
@@ -1,9 +1,48 @@
 package org.w3.sw.directmapping
 
-object DirectMapping {
+import org.w3.sw._
 
-  import org.w3.sw.rdb.RDB._
-  import org.w3.sw.rdf._
+import org.w3.sw.rdb.RDB._
+
+trait DirectMapping[IRI,
+                    Graph <: Traversable[Triple],
+                    Triple,
+                    BNode,
+                    Node,
+                    NodeIRI <: Node,
+                    NodeBNode <: Node,
+                    Subject,
+                    SubjectNode <: Subject,
+                    Predicate,
+                    PredicateIRI <: Predicate,
+                    Object,
+                    ObjectNode <: Object,
+                    ObjectLiteral <: Object,
+                    Literal,
+                    PlainLiteral <: Literal,
+                    TypedLiteral <: Literal,
+                    LangTag] {
+
+  val RDFModule:RDFModule[IRI,
+                          Graph,
+                          Triple,
+                          BNode,
+                          Node,
+                          NodeIRI,
+                          NodeBNode,
+                          Subject,
+                          SubjectNode,
+                          Predicate,
+                          PredicateIRI,
+                          Object,
+                          ObjectNode,
+                          ObjectLiteral,
+                          Literal,
+                          PlainLiteral,
+                          TypedLiteral,
+                          LangTag]
+
+  import RDFModule._
 
   /** A KeyMap associates the candidate key and key values with the
    * node for any tuple in a unique relation. */
@@ -101,10 +140,10 @@
       if (r.pk.isDefined) {
 	/** Table has a primkary key. */
 	val vs = t.lexvaluesNoNulls(r.pk.get.attrs)
-	nodemap(r.name, r.pk.get.attrs, vs)
+	NodeIRI(nodemap(r.name, r.pk.get.attrs, vs))
       } else
 	/** Table has no primkary key (but has some candidate keys). */
-	freshbnode()
+	NodeBNode(freshbnode())
     (r.candidates.map(k => {
       val values:List[CellValue] = k.attrs.map(a => t(a))
       (k, values)
@@ -115,7 +154,7 @@
   def directDB (db:Database) : Graph = {
     val idxables = db.keySet.toSet filter { rn => !db(rn).candidates.isEmpty }
     val nodeMap:NodeMap = idxables map {rn => rn -> relation2KeyMap(db(rn))}
-    db.keySet.toSet.flatMap((rn:RelName) => directR(db(rn), nodeMap, db))
+    Graph(db.keySet flatMap  { (rn:RelName) => directR(db(rn), nodeMap, db) })
   }
 
   def directR (r:Relation, nodes:NodeMap, db:Database) : Graph =
@@ -123,7 +162,7 @@
      * We know this because relations with candidate keys are mapped to unique
      * subjects, and potentially redundant rows get unique blank node subjects.
      */
-    r.body.flatMap(t => directT(t, r, nodes, db)).toSet
+    Graph(r.body flatMap { t => directT(t, r, nodes, db) })
 
   def directT (t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
     val s:Node =
@@ -134,7 +173,7 @@
 	nodes.ultimateReferent(r.name, k, vs, db)
       } else
 	/** Table has no candidate keys. */
-	freshbnode()
+	NodeBNode(freshbnode())
     directS(s, t, r, nodes, db)
   }
 
@@ -154,7 +193,9 @@
     val p = predicatemap (rn, List(a))
     val l = t.lexvalue(a).get
     val o = literalmap(l, h.sqlDatatype(a))
-    Triple(s, p, o)
+    Triple(SubjectNode(s),
+           PredicateIRI(p),
+           ObjectLiteral(o))
   }
   def directN (s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
     val p = predicatemap (r.name, as)
@@ -166,8 +207,8 @@
       error("Relation " + target.rel + " has no attributes (" + target.key + ") to match " + r.name + t)
     if (!nodes(target.rel)(target.key).contains(ls))
       error("Relation " + target.rel + "(" + target.key + ") has no values " + ls + " to match " + r.name + t)
-    val o:Object = nodes(target.rel)(target.key)(ls)
-    Triple(s, p, o)
+    val o:Object = ObjectNode(nodes(target.rel)(target.key)(ls))
+    Triple(SubjectNode(s), PredicateIRI(p), o)
   }
 
   // These implicits make nodemap and predicatemap functions prettier.
--- a/directmapping/src/test/scala/DirectMappingTest.scala	Fri Jan 07 12:50:06 2011 -0500
+++ b/directmapping/src/test/scala/DirectMappingTest.scala	Fri Jan 07 19:20:00 2011 -0500
@@ -1,17 +1,76 @@
 package org.w3.sw.directmapping
 
-import org.w3.sw.rdf._
+import org.w3.sw._
 import org.w3.sw.rdb.RDB._
 import org.w3.sw.sql
-import org.w3.sw.turtle
-import org.w3.sw.directmapping.DirectMapping._
+import org.w3.sw.turtle.Turtle
+//import org.w3.sw.directmapping.DirectMapping
 import java.io.File
 
 import org.scalatest.FunSuite
 
-class FundamentalTest extends FunSuite {
+class FundamentalTestWithRDF extends FundamentalTest(RDFConcreteModuleWithImplicits)
 
- test("NodeMap") {
+abstract class FundamentalTest[IRI,
+                          Graph <: Traversable[Triple],
+                          Triple,
+                          BNode,
+                          Node,
+                          NodeIRI <: Node,
+                          NodeBNode <: Node,
+                          Subject,
+                          SubjectNode <: Subject,
+                          Predicate,
+                          PredicateIRI <: Predicate,
+                          Object,
+                          ObjectNode <: Object,
+                          ObjectLiteral <: Object,
+                          Literal,
+                          PlainLiteral <: Literal,
+                          TypedLiteral <: Literal,
+                          LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
+                                                                        Graph,
+                                                                        Triple,
+                                                                        BNode,
+                                                                        Node,
+                                                                        NodeIRI,
+                                                                        NodeBNode,
+                                                                        Subject,
+                                                                        SubjectNode,
+                                                                        Predicate,
+                                                                        PredicateIRI,
+                                                                        Object,
+                                                                        ObjectNode,
+                                                                        ObjectLiteral,
+                                                                        Literal,
+                                                                        PlainLiteral,
+                                                                        TypedLiteral,
+                                                                        LangTag])
+extends FunSuite { self =>
+
+  import RDFModule._
+
+  val DirectMapping = new DirectMapping[IRI,
+                                        Graph,
+                                        Triple,
+                                        BNode,
+                                        Node,
+                                        NodeIRI,
+                                        NodeBNode,
+                                        Subject,
+                                        SubjectNode,
+                                        Predicate,
+                                        PredicateIRI,
+                                        Object,
+                                        ObjectNode,
+                                        ObjectLiteral,
+                                        Literal,
+                                        PlainLiteral,
+                                        TypedLiteral,
+                                        LangTag] { val RDFModule = self.RDFModule }
+  import DirectMapping._
+
+  test("NodeMap") {
 
     val ck1:CandidateKey = CandidateKey("name", "ssn")
     val ck2:CandidateKey = CandidateKey("ID")
@@ -19,8 +78,8 @@
     val v21:List[CellValue] = List(LexicalValue("alice"), LexicalValue("8"))
     val v12:List[CellValue] = List(LexicalValue("18"))
     val v22:List[CellValue] = List(LexicalValue("23"))
-    val s1:Node = BNode("1")
-    val s2:Node = BNode("2")
+    val s1:Node = NodeBNode(BNode("1"))
+    val s2:Node = NodeBNode(BNode("2"))
     val data:Set[(List[(CandidateKey, List[CellValue])], Node)] =
       Set((List((ck1, v11),(ck2, v21)), s1),
 	  (List((ck1, v12),(ck2, v22)), s2))
@@ -37,10 +96,94 @@
 
 }
 
-class Test extends FunSuite {
+
+
+
+
+
+class DirectMappingTestWithRDF extends DirectMappingTest(RDFConcreteModuleWithImplicits)
+
+
+
+abstract class DirectMappingTest[IRI,
+                                 Graph <: Traversable[Triple],
+                                 Triple,
+                                 BNode,
+                                 Node,
+                                 NodeIRI <: Node,
+                                 NodeBNode <: Node,
+                                 Subject,
+                                 SubjectNode <: Subject,
+                                 Predicate,
+                                 PredicateIRI <: Predicate,
+                                 Object,
+                                 ObjectNode <: Object,
+                                 ObjectLiteral <: Object,
+                                 Literal,
+                                 PlainLiteral <: Literal,
+                                 TypedLiteral <: Literal,
+                                 LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
+                                                                               Graph,
+                                                                               Triple,
+                                                                               BNode,
+                                                                               Node,
+                                                                               NodeIRI,
+                                                                               NodeBNode,
+                                                                               Subject,
+                                                                               SubjectNode,
+                                                                               Predicate,
+                                                                               PredicateIRI,
+                                                                               Object,
+                                                                               ObjectNode,
+                                                                               ObjectLiteral,
+                                                                               Literal,
+                                                                               PlainLiteral,
+                                                                               TypedLiteral,
+                                                                               LangTag])
+extends FunSuite { self =>
+
+  import RDFModule._
+
+  val DirectMapping = new DirectMapping[IRI,
+                                        Graph,
+                                        Triple,
+                                        BNode,
+                                        Node,
+                                        NodeIRI,
+                                        NodeBNode,
+                                        Subject,
+                                        SubjectNode,
+                                        Predicate,
+                                        PredicateIRI,
+                                        Object,
+                                        ObjectNode,
+                                        ObjectLiteral,
+                                        Literal,
+                                        PlainLiteral,
+                                        TypedLiteral,
+                                        LangTag] { val RDFModule = self.RDFModule }
+  import DirectMapping._
 
   val SqlParser = sql.SqlParser()
-  val TurtleParser = turtle.Turtle()
+
+  val TurtleParser = new Turtle[IRI,
+                                Graph,
+                                Triple,
+                                BNode,
+                                Node,
+                                NodeIRI,
+                                NodeBNode,
+                                Subject,
+                                SubjectNode,
+                                Predicate,
+                                PredicateIRI,
+                                Object,
+                                ObjectNode,
+                                ObjectLiteral,
+                                Literal,
+                                PlainLiteral,
+                                TypedLiteral,
+                                LangTag] { val RDFModule = self.RDFModule }
 
   def testDirectMapping(testName:String, db:Database, expectedGraph:Graph):Unit =
     test(testName) {
@@ -50,7 +193,7 @@
 
   def testDirectMapping(testName:String, dbFile:File, expectedGraphFile:File):Unit = {
     val db = SqlParser.toDB(dbFile)
-    val expectedGraph = TurtleParser.toGraph(expectedGraphFile)
+    val expectedGraph:Graph = TurtleParser.toGraph(expectedGraphFile)
     testDirectMapping(testName, db, expectedGraph)
   }
 
--- a/rdf/src/main/scala/RDF.scala	Fri Jan 07 12:50:06 2011 -0500
+++ b/rdf/src/main/scala/RDF.scala	Fri Jan 07 19:20:00 2011 -0500
@@ -1,66 +1,97 @@
 package org.w3.sw
 
-trait RDFModel {
+import org.w3.isomorphic._
 
-  import org.w3.isomorphic._
+trait RDFModule[IRI,
+                Graph <: Traversable[Triple],
+                Triple,
+                BNode,
+                Node,
+                NodeIRI <: Node,
+                NodeBNode <: Node,
+                Subject,
+                SubjectNode <: Subject,
+                Predicate,
+                PredicateIRI <: Predicate,
+                Object,
+                ObjectNode <: Object,
+                ObjectLiteral <: Object,
+                Literal,
+                PlainLiteral <: Literal,
+                TypedLiteral <: Literal,
+                LangTag] {
 
-  type IRI
   val IRI : Isomorphic1[String, IRI]
 
-  // it should actually be an Ordered Set
-  type Graph <: Traversable[Triple]
   val Graph : {
     def empty:Graph
     def apply(elems:Triple*):Graph
     def apply(it:Iterable[Triple]):Graph
   }
 
-  type Triple
   val Triple : Isomorphic3[Subject, Predicate, Object, Triple]
 
-  type BNode
   val BNode : Isomorphic1[String, BNode]
 
-  // sealed type Node: NodeIRI NodeBNode
-  type Node
-  type NodeIRI   <: Node
-  type NodeBNode <: Node
   val NodeIRI   : Isomorphic1[IRI, NodeIRI]
   val NodeBNode : Isomorphic1[BNode, NodeBNode]
 
-  type Subject
-  type SubjectNode <: Subject
   val SubjectNode : Isomorphic1[Node, SubjectNode]
 
-  type Predicate
-  type PredicateIRI <: Predicate
   val PredicateIRI : Isomorphic1[IRI, PredicateIRI]
 
-  type Object
-  type ObjectNode    <: Object
-  type ObjectLiteral <: Object
   val ObjectNode    : Isomorphic1[Node, ObjectNode]
   val ObjectLiteral : Isomorphic1[Literal, ObjectLiteral]
 
-  // val lexicalForm:String
-  type Literal
-  type PlainLiteral <: Literal
-  type TypedLiteral <: Literal
   val PlainLiteral : Isomorphic2[String, Option[LangTag], PlainLiteral]
   val TypedLiteral : Isomorphic2[String, IRI, TypedLiteral]
 
-  type LangTag
   val LangTag : Isomorphic1[String, LangTag]
 
-  val StringDatatype = IRI("http://www.w3.org/2001/XMLSchema#string")
-  val IntegerDatatype = IRI("http://www.w3.org/2001/XMLSchema#integer")
-  val DateDatatype = IRI("http://www.w3.org/2001/XMLSchema#date")
-  val DateTimeDatatype = IRI("http://www.w3.org/2001/XMLSchema#dateTime")
+  lazy val StringDatatype = IRI("http://www.w3.org/2001/XMLSchema#string")
+  lazy val IntegerDatatype = IRI("http://www.w3.org/2001/XMLSchema#integer")
+  lazy val DateDatatype = IRI("http://www.w3.org/2001/XMLSchema#date")
+  lazy val DateTimeDatatype = IRI("http://www.w3.org/2001/XMLSchema#dateTime")
 
 }
 
-trait RDFImplicits extends RDFModel {
 
+trait RDFModuleWithImplicits[IRI,
+                             Graph <: Traversable[Triple],
+                             Triple,
+                             BNode,
+                             Node,
+                             NodeIRI <: Node,
+                             NodeBNode <: Node,
+                             Subject,
+                             SubjectNode <: Subject,
+                             Predicate,
+                             PredicateIRI <: Predicate,
+                             Object,
+                             ObjectNode <: Object,
+                             ObjectLiteral <: Object,
+                             Literal,
+                             PlainLiteral <: Literal,
+                             TypedLiteral <: Literal,
+                             LangTag]
+extends RDFModule[IRI,
+                  Graph,
+                  Triple,
+                  BNode,
+                  Node,
+                  NodeIRI,
+                  NodeBNode,
+                  Subject,
+                  SubjectNode,
+                  Predicate,
+                  PredicateIRI,
+                  Object,
+                  ObjectNode,
+                  ObjectLiteral,
+                  Literal,
+                  PlainLiteral,
+                  TypedLiteral,
+                  LangTag] {
   implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
   implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
   implicit def node2subjectnode(n:Node):Subject = SubjectNode(n)
@@ -74,9 +105,7 @@
   implicit def plain2object(b:PlainLiteral):Object = ObjectLiteral(b)
 }
 
-trait RDF extends RDFModel {
-
-  import org.w3.isomorphic._
+object RDFConcreteModel {
 
   case class IRI(iri:String) { override def toString = '"' + iri + '"' }
   object IRI extends Isomorphic1[String, IRI]
@@ -129,72 +158,56 @@
 
 }
 
-object RDF extends RDF
-
-// object rdf {
-
-//   case class Graph(triples:Set[Triple])
-//   object Graph {
-//     def empty:Graph = Graph(Set[Triple]())
-//     def apply(elems:Triple*):Graph = Graph(Set[Triple](elems:_*))
-//     def apply(it:Iterable[Triple]):Graph = Graph(it.toSet)
-//   }
-
-// case class Triple (s:Subject, p:Predicate, o:Object)
-
-// sealed abstract class Node // factor out IRIs and BNodes
-// case class NodeIRI(i:IRI) extends Node
-// implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
-// case class NodeBNode(b:BNode) extends Node
-// implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
-
-// sealed abstract class Subject
-// case class SubjectNode(n:Node) extends Subject
-// implicit def node2subjectnode(n:Node):Subject = SubjectNode(n)
-// implicit def iri2subjectnode(i:IRI):Subject = SubjectNode(i)
-// implicit def bnode2subjectnode(b:BNode):Subject = SubjectNode(b)
-
-// sealed abstract class Predicate
-// case class PredicateIRI(i:IRI) extends Predicate
-// implicit def iri2predicateiri(i:IRI):Predicate = PredicateIRI(i)
+import RDFConcreteModel._
+trait RDFConcreteModule extends RDFModule[IRI,
+                                          Graph,
+                                          Triple,
+                                          BNode,
+                                          Node,
+                                          NodeIRI,
+                                          NodeBNode,
+                                          Subject,
+                                          SubjectNode,
+                                          Predicate,
+                                          PredicateIRI,
+                                          Object,
+                                          ObjectNode,
+                                          ObjectLiteral,
+                                          Literal,
+                                          PlainLiteral,
+                                          TypedLiteral,
+                                          LangTag] {
+  val IRI = RDFConcreteModel.IRI
+  val Graph = RDFConcreteModel.Graph
+  val Triple = RDFConcreteModel.Triple
+  val BNode = RDFConcreteModel.BNode
+  val NodeIRI = RDFConcreteModel.NodeIRI
+  val NodeBNode = RDFConcreteModel.NodeBNode
+  val SubjectNode = RDFConcreteModel.SubjectNode
+  val PredicateIRI = RDFConcreteModel.PredicateIRI
+  val ObjectNode = RDFConcreteModel.ObjectNode
+  val ObjectLiteral = RDFConcreteModel.ObjectLiteral
+  val PlainLiteral = RDFConcreteModel.PlainLiteral
+  val TypedLiteral = RDFConcreteModel.TypedLiteral
+  val LangTag = RDFConcreteModel.LangTag
+}
 
-// sealed abstract class Object
-// case class ObjectNode(n:Node) extends Object
-// implicit def node2objectnode(n:Node):Object = ObjectNode(n)
-// implicit def iri2objectnode(i:IRI):Object = ObjectNode(i)
-// implicit def bnode2objectnode(b:BNode):Object = ObjectNode(b)
-// case class ObjectLiteral (n:Literal) extends Object
-
-// case class IRI(iri:String) {
-//   override def toString = '"' + iri + '"'
-// }
-// case class BNode(label:String)
-
-//   sealed abstract class Literal(val lexicalForm:String)
-
-//   case class PlainLiteral(override val lexicalForm:String, langtag:Option[LangTag]) extends Literal(lexicalForm) {
-//     override def toString = "\"" + lexicalForm + "\"" + { if (langtag.isDefined) langtag.get }
-//   }
-//   implicit def typed2object(i:TypedLiteral):Object = ObjectLiteral(i)
-
-//   case class TypedLiteral(override val lexicalForm:String, datatype:IRI) extends Literal(lexicalForm) {
-//     override def toString = "\"" + lexicalForm + "\"^^" + datatype
-//   }
-//   implicit def plain2object(b:PlainLiteral):Object = ObjectLiteral(b)
-
-//   case class LangTag(s:String)
-
-// val StringDatatype = IRI("http://www.w3.org/2001/XMLSchema#string")
-// val IntegerDatatype = IRI("http://www.w3.org/2001/XMLSchema#integer")
-// val DateDatatype = IRI("http://www.w3.org/2001/XMLSchema#date")
-// val DateTimeDatatype = IRI("http://www.w3.org/2001/XMLSchema#dateTime")
-
-// }
-
-// // object Literal {
-// //   val StringDatatype = Datatype(IRI("http://www.w3.org/2001/XMLSchema#string"))
-// //   val IntegerDatatype = Datatype(IRI("http://www.w3.org/2001/XMLSchema#integer"))
-// //   val DateDatatype = Datatype(IRI("http://www.w3.org/2001/XMLSchema#date"))
-// //   // val DateTimeDatatype = Datatype(IRI("http://www.w3.org/2001/XMLSchema#dateTime"))
-// // }
-
+object RDFConcreteModule extends RDFConcreteModule
+object RDFConcreteModuleWithImplicits extends RDFConcreteModule with RDFModuleWithImplicits[IRI,
+                                                                                            Graph,
+                                                                                            Triple,
+                                                                                            BNode,
+                                                                                            Node,
+                                                                                            NodeIRI,
+                                                                                            NodeBNode,
+                                                                                            Subject,
+                                                                                            SubjectNode,
+                                                                                            Predicate,
+                                                                                            PredicateIRI,
+                                                                                            Object,
+                                                                                            ObjectNode,
+                                                                                            ObjectLiteral,
+                                                                                            Literal,
+                                                                                            PlainLiteral,
+                                                                                            TypedLiteral,
+                                                                                            LangTag]
--- a/turtle/src/main/scala/turtle.scala	Fri Jan 07 12:50:06 2011 -0500
+++ b/turtle/src/main/scala/turtle.scala	Fri Jan 07 19:20:00 2011 -0500
@@ -1,6 +1,6 @@
 package org.w3.sw.turtle
 
-import org.w3.sw.RDFModel
+import org.w3.sw._
 //import org.w3.sw.{RDF => RDFModel}
 import scala.util.parsing.combinator._
 import java.net.URI
@@ -15,78 +15,115 @@
 
 import MyParsers._
 
-case class Turtle(RDFModel:RDFModel) extends JavaTokenParsers {
-
-  import RDFModel._
-
-  def toGraph(t:String):Graph = parseAll(turtle, t).get
-
-  def toGraph(file:java.io.File):Graph = {
-    val t = scala.io.Source.fromFile(file).getLines.reduceLeft(_+_)
-    parseAll(turtle, t).get
-  }
-
-  def turtle:Parser[Graph] =
-    opt(triplesblock) ^^ { case tbOPT => tbOPT.getOrElse(Graph.empty) }
-
-  def prefixdecl:Parser[Unit] =
-    "@prefix" ~ name ~ ":" ~ qnameORuri ~ "." ^^ { case "@prefix"~pre~":"~u~"." => prefixes += (pre -> { val IRI(iri) = u ; iri }) }
-
-  def triplesblock:Parser[Graph] =
-    rep(triplepatternOrPrefixOrBase) ^^ { case pats => Graph(pats.flatten) }
-
-  def triplepatternOrPrefixOrBase:Parser[Option[Triple]] = (
-      triplepattern ^^ { case p => Some(p) }
-    | prefixdecl ^^ { case _ => None }
-  )
-
-  def triplepattern:Parser[Triple] =
-    subject ~ predicate ~ objectt ~ "." ^^ { case s~p~o~"." => Triple(s, p, o) }
-
-  def subject:Parser[Subject] = (
-      qnameORuri ^^ { case x => SubjectNode(NodeIRI(x)) }
-    | bnode ^^ { case x => SubjectNode(NodeBNode(x)) }
-  )
+trait Turtle[IRI,
+             Graph <: Traversable[Triple],
+             Triple,
+             BNode,
+             Node,
+             NodeIRI <: Node,
+             NodeBNode <: Node,
+             Subject,
+             SubjectNode <: Subject,
+             Predicate,
+             PredicateIRI <: Predicate,
+             Object,
+             ObjectNode <: Object,
+             ObjectLiteral <: Object,
+             Literal,
+             PlainLiteral <: Literal,
+             TypedLiteral <: Literal,
+             LangTag]
+ extends JavaTokenParsers {
+               
+   val RDFModule:RDFModule[IRI,
+                           Graph,
+                           Triple,
+                           BNode,
+                           Node,
+                           NodeIRI,
+                           NodeBNode,
+                           Subject,
+                           SubjectNode,
+                           Predicate,
+                           PredicateIRI,
+                           Object,
+                           ObjectNode,
+                           ObjectLiteral,
+                           Literal,
+                           PlainLiteral,
+                           TypedLiteral,
+                           LangTag]
 
-  def predicate:Parser[Predicate] = (
-      qnameORuri ^^ { case x => PredicateIRI(x) }
-    | "a" ^^ { x => PredicateIRI(IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) }
-  )
-
-  def objectt:Parser[Object] = (
-      qnameORuri ^^ { case x => ObjectNode(NodeIRI(x)) }
-    | bnode ^^ { case x => ObjectNode(NodeBNode(x)) }
-    | literal ^^ { case x => ObjectLiteral(x) }
-  )
+   import RDFModule._
 
-  def qnameORuri:Parser[IRI] = (
-      "<"~uri~">" ^^ { case "<"~x~">" => IRI(x) }
-    | name~":"~name ^^ {
-      case prefix~":"~localName => try {
-	IRI(prefixes(prefix) + localName)
-      } catch {
-	case e:java.util.NoSuchElementException =>
-	  throw new Exception("unknown prefix " + prefix)
-      }
-    }
-  )
+   def toGraph(t:String):Graph = parseAll(turtle, t).get
 
-  def bnode:Parser[BNode] =
-    "_:"~name ^^ { case "_:"~name => BNode(name) }
+   def toGraph(file:java.io.File):Graph = {
+     val t = scala.io.Source.fromFile(file).getLines.reduceLeft(_+_)
+     parseAll(turtle, t).get
+   }
 
-  def literal:Parser[Literal] = (
-      stringLiteral~"^^"~qnameORuri ^^
-      {
-	case lit~"^^"~dt => TypedLiteral(lit.substring(1,lit.size - 1), dt match {
- 	  case IRI("http://www.w3.org/2001/XMLSchema#string") => StringDatatype
- 	  case IRI("http://www.w3.org/2001/XMLSchema#integer") => IntegerDatatype
- 	  case IRI("http://www.w3.org/2001/XMLSchema#date") => DateDatatype
- 	  case IRI("http://www.w3.org/2001/XMLSchema#dateTime") => DateTimeDatatype
- 	  case x => error("only programed to deal with string and integer, not " + x)
- 	})
-      }
-    | integer ^^ { l => TypedLiteral(l, IntegerDatatype) }
-  )
+   def turtle:Parser[Graph] =
+     opt(triplesblock) ^^ { case tbOPT => tbOPT.getOrElse(RDFModule.Graph.empty) }
+
+   def prefixdecl:Parser[Unit] =
+     "@prefix" ~ name ~ ":" ~ qnameORuri ~ "." ^^ { case "@prefix"~pre~":"~u~"." => prefixes += (pre -> { val IRI(iri) = u ; iri }) }
+
+   def triplesblock:Parser[Graph] =
+     rep(triplepatternOrPrefixOrBase) ^^ { case pats => Graph(pats.flatten) }
+ 
+   def triplepatternOrPrefixOrBase:Parser[Option[Triple]] = (
+       triplepattern ^^ { case p => Some(p) }
+     | prefixdecl ^^ { case _ => None }
+   )
+ 
+   def triplepattern:Parser[Triple] =
+     subject ~ predicate ~ objectt ~ "." ^^ { case s~p~o~"." => Triple(s, p, o) }
+ 
+   def subject:Parser[Subject] = (
+       qnameORuri ^^ { case x => SubjectNode(NodeIRI(x)) }
+     | bnode ^^ { case x => SubjectNode(NodeBNode(x)) }
+   )
+ 
+   def predicate:Parser[Predicate] = (
+       qnameORuri ^^ { case x => PredicateIRI(x) }
+     | "a" ^^ { x => PredicateIRI(IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) }
+   )
+ 
+   def objectt:Parser[Object] = (
+       qnameORuri ^^ { case x => ObjectNode(NodeIRI(x)) }
+     | bnode ^^ { case x => ObjectNode(NodeBNode(x)) }
+     | literal ^^ { case x => ObjectLiteral(x) }
+   )
+ 
+   def qnameORuri:Parser[IRI] = (
+       "<"~uri~">" ^^ { case "<"~x~">" => IRI(x) }
+     | name~":"~name ^^ {
+       case prefix~":"~localName => try {
+ 	IRI(prefixes(prefix) + localName)
+       } catch {
+ 	case e:java.util.NoSuchElementException =>
+ 	  throw new Exception("unknown prefix " + prefix)
+       }
+     }
+   )
+ 
+   def bnode:Parser[BNode] =
+     "_:"~name ^^ { case "_:"~name => BNode(name) }
+ 
+   def literal:Parser[Literal] = (
+       stringLiteral~"^^"~qnameORuri ^^
+       {
+ 	case lit~"^^"~dt => TypedLiteral(lit.substring(1,lit.size - 1), dt match {
+  	  case IRI("http://www.w3.org/2001/XMLSchema#string") => StringDatatype
+  	  case IRI("http://www.w3.org/2001/XMLSchema#integer") => IntegerDatatype
+  	  case IRI("http://www.w3.org/2001/XMLSchema#date") => DateDatatype
+  	  case IRI("http://www.w3.org/2001/XMLSchema#dateTime") => DateTimeDatatype
+  	  case x => error("only programed to deal with string and integer, not " + x)
+  	})
+       }
+     | integer ^^ { l => TypedLiteral(l, IntegerDatatype) }
+   )
 
 }
 
--- a/turtle/src/test/scala/turtleTest.scala	Fri Jan 07 12:50:06 2011 -0500
+++ b/turtle/src/test/scala/turtleTest.scala	Fri Jan 07 19:20:00 2011 -0500
@@ -1,15 +1,67 @@
 package org.w3.sw.turtle
 
-import org.w3.sw.{RDF, RDFModel, RDFImplicits}
+import org.w3.sw._
 import org.scalatest.FunSuite
 
-class TurtleTestWithRDF extends TurtleTest(new RDF with RDFImplicits {  })
+class TurtleTestWithRDF extends TurtleTest(RDFConcreteModuleWithImplicits)
 
-abstract class TurtleTest(RDFModel:RDFModel with RDFImplicits) extends FunSuite {
+abstract class TurtleTest[IRI,
+                          Graph <: Traversable[Triple],
+                          Triple,
+                          BNode,
+                          Node,
+                          NodeIRI <: Node,
+                          NodeBNode <: Node,
+                          Subject,
+                          SubjectNode <: Subject,
+                          Predicate,
+                          PredicateIRI <: Predicate,
+                          Object,
+                          ObjectNode <: Object,
+                          ObjectLiteral <: Object,
+                          Literal,
+                          PlainLiteral <: Literal,
+                          TypedLiteral <: Literal,
+                          LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
+                                                                        Graph,
+                                                                        Triple,
+                                                                        BNode,
+                                                                        Node,
+                                                                        NodeIRI,
+                                                                        NodeBNode,
+                                                                        Subject,
+                                                                        SubjectNode,
+                                                                        Predicate,
+                                                                        PredicateIRI,
+                                                                        Object,
+                                                                        ObjectNode,
+                                                                        ObjectLiteral,
+                                                                        Literal,
+                                                                        PlainLiteral,
+                                                                        TypedLiteral,
+                                                                        LangTag])
+extends FunSuite { self =>
 
-  import RDFModel._
+  import RDFModule._
 
-  val turtleParser = Turtle(RDFModel)
+  val turtleParser = new Turtle[IRI,
+                                Graph,
+                                Triple,
+                                BNode,
+                                Node,
+                                NodeIRI,
+                                NodeBNode,
+                                Subject,
+                                SubjectNode,
+                                Predicate,
+                                PredicateIRI,
+                                Object,
+                                ObjectNode,
+                                ObjectLiteral,
+                                Literal,
+                                PlainLiteral,
+                                TypedLiteral,
+                                LangTag] { val RDFModule = self.RDFModule }
 
   test("directgraph_emp_adder") {
     val directgraph_emp_adder:Graph =