Skip to content
leithaus edited this page Sep 14, 2010 · 7 revisions

Welcome to the SpecialK wiki!

Here is a little Scala project to experiment with the intersection of DataLog semantics and NoSql. What i did was

  • build a simple TupleSpace using delimited continuations
  • use as keys in the TupleSpace structures that support a natural notion of unification (i.e. essentially isomorphic to Prolog terms)
  • use unification in the get/put semantics of the TupleSpace operations
    The code is rough and ready — certainly not for the faint of heart.

Now, here’s a question for the delimited continuations aficionados. Currently, a client of the TupleSpace that is issuing a get is required to supply a continuation to be picked up when a value arrives at a location matching the pattern of the get. The guarantee the TupleSpace makes is never to fire the continuation unless and until there is a value available at that location. The question is, is there a way to extrude the scope of the reset so that the client is not required to supply the continuation, but is instead left suspended until the value is available? i believe the answer is no, but would love to be proven wrong.

Here’s a sample session:

Welcome to Scala version 2.8.0.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.
scala> Recompiling 1 files
import com.biosimilarity.lib._
import com.biosimilarity.lib._
Recompiling 1 files
Recompiling 1 files
Recompiling 1 files
Recompiling 1 files
Recompiling 1 files
import com.biosimilarity.lib._
scala> import com.biosimilarity.store._
import com.biosimilarity.store._
Recompiling 1 files
Recompiling 1 files
import com.biosimilarity.store._

Make a TupleSpace in which the places are labeled by terms up to unification

scala> object TStore extends TermStore[String,String,String,Int]( Blogger() )
object TStore extends TermStore[String,String,String,Int]( Blogger() )
Recompiling 1 files
Recompiling 1 files
defined module TStore

Make a continuation for reporting

scala> val pl = ( v : Option[TStore.Resource] ) => {println( "v = " + v ); v}
val pl = ( v : Option[TStore.Resource] ) => {println( "v = " + v ); v}
Recompiling 1 files
Recompiling 1 files
pl: (Option[TStore.Resource]) => Option[TStore.Resource] = <function1>

Make a ground term label for a location in the TupleSpace (the equivalent Prolog term structure is agents( work( tag( mcc ), tag( msft ) ) ) )

scala> val cBranch1 = new CnxnBranch[String,String]( "agents", List( new CnxnBranch[String,String]( "work", List( new CnxnLeaf[String,String]( "mcc" ), new CnxnLeaf[String,String]( "msft" ) ) ) ) )
val cBranch1 = new CnxnBranch[String,String]( "agents", List( new CnxnBranch[String,String]( "work", List( new CnxnLeaf[String,String]( "mcc" ), new CnxnLeaf[String,String]( "msft" ) ) ) ) )
Recompiling 1 files
Recompiling 1 files
cBranch1: com.biosimilarity.store.CnxnBranch[String,String] = com.biosimilarity.store.CnxnBranch@52ac5024

Make another one (the equivalent Prolog term structure is agents( work( tag( mcc ), tag( iful ) ) ) )

scala> val cBranch2 = new CnxnBranch[String,String]( "agents", List( new CnxnBranch[String,String]( "work", List( new CnxnLeaf[String,String]( "mcc" ), new CnxnLeaf[String,String]( "iful" ) ) ) ) )
val cBranch2 = new CnxnBranch[String,String]( "agents", List( new CnxnBranch[String,String]( "work", List( new CnxnLeaf[String,String]( "mcc" ), new CnxnLeaf[String,String]( "iful" ) ) ) ) )
Recompiling 1 files
Recompiling 1 files
cBranch2: com.biosimilarity.store.CnxnBranch[String,String] = com.biosimilarity.store.CnxnBranch@6cb77928

Make a term pattern (the equivalent Prolog term structure is agents( work( tag( mcc ), tag( XM ) ) ) )

scala> val cCtxtBranch1 = new CnxnCtxtBranch[String,String,String]( "agents", List( new CnxnCtxtBranch[String,String,String]( "work", List( new CnxnCtxtLeaf[String,String,String]( Left( "mcc" ) ), new CnxnCtxtLeaf[String,String,String]( Right( "M" ) ) ) ) ) )
val cCtxtBranch1 = new CnxnCtxtBranch[String,String,String]( "agents", List( new CnxnCtxtBranch[String,String,String]( "work", List( new CnxnCtxtLeaf[String,String,String]( Left( "mcc" ) ), new CnxnCtxtLeaf[String,String,String]( Right( "M" ) ) ) ) ) )
Recompiling 1 files
Recompiling 1 files
cCtxtBranch1: com.biosimilarity.store.CnxnCtxtBranch[String,String,String] = com.biosimilarity.store.CnxnCtxtBranch@6e6e8d02

Put a value at a location (logically, TStore now looks like a map ( (agents( work( tag( mcc ), tag( msft ) ) ) -> 1 ) )

scala> TStore.put( cBranch1, 1 )
TStore.put( cBranch1, 1 )
Recompiling 1 files
Recompiling 1 files

Retrieve all values matching a pattern (get values stored at locations matching agents( work( tag( mcc ), tag( XM ) ) ) ; since this pattern unifies with agents( work( tag( mcc ), tag( msft ) ) ) we expect to get a 1 back — which we do, essentially)

scala> TStore.get( cCtxtBranch1, pl )
TStore.get( cCtxtBranch1, pl )
Recompiling 1 files
Recompiling 1 files
number of places = 1
_labelMap rows before delete : 1
deleting row labeled by agents( work( tag( mcc ) , tag( msft ) ) )
_labelMap rows after delete : 0
res1: Seq[Option[TStore.Resource]] = List(Some(Right(1)))

Retrieve all values matching a pattern (get values stored at locations matching agents( work( tag( mcc ), tag( XM ) ) ) ; since this pattern does not unify with anything we expect our continuation to be held onto until a value is deposited in a location matching the pattern)

scala> TStore.get( cCtxtBranch1, pl )
TStore.get( cCtxtBranch1, pl )
Recompiling 1 files
Recompiling 1 files
number of places = 0
pivot point
pivot back, rslt = None
res2: Seq[Option[TStore.Resource]] = List(None)

Put a value at a location (add the Tuple ( (agents( work( tag( mcc ), tag( msft ) ) ) -> 1 ) to the store — which fires the continuation waiting at the pattern )

scala> TStore.put( cBranch1, 1 )
TStore.put( cBranch1, 1 )
Recompiling 1 files
Recompiling 1 files
pivot back, rslt = Some(Right(1))
_labelMap rows at pivot before delete : 0
deleting row labeled by agents( work( tag( mcc ) , tag( XM ) ) )
_labelMap rows at pivot after delete : 0
v = Some(Right(1))

Retrieve all values matching a pattern (get values stored at locations matching agents( work( tag( mcc ), tag( XM ) ) ) ; since the last put was consumed by the waiting get, this pattern does not unify with anything we expect our continuation to held onto until a value is deposited in a location matching the pattern)

scala> TStore.get( cCtxtBranch1, pl )
TStore.get( cCtxtBranch1, pl )
Recompiling 1 files
Recompiling 1 files
number of places = 0
pivot point
pivot back, rslt = None
res4: Seq[Option[TStore.Resource]] = List(None)

Put a value at a different location (that still matches our pattern)

scala> TStore.put( cBranch2, 3 )
TStore.put( cBranch2, 3 )
Recompiling 1 files
Recompiling 1 files
pivot back, rslt = Some(Right(3))
_labelMap rows at pivot before delete : 0
deleting row labeled by agents( work( tag( mcc ) , tag( XM ) ) )
_labelMap rows at pivot after delete : 0
v = Some(Right(3))
scala>