Messages

asGoal message

"False, protocol *MicroKanren-core"
asGoal

   ^ Failed new
"True, protocol *MicroKanren-core"
asGoal

   ^ Succeed new
"BlockClosure, protocol *MicroKanren-core"
asGoal

   ^ (numArgs = 0
         ifTrue: [ Eta new ]
         ifFalse: [ Fresh new ])
        receiver: self;
        yourself

onState: message

This is the fundamental message of the whole system because it allows us to explore the search space of both succeeding and failing states.

"Goal, protocol running"
onState: aState

   <doc: #Realog topic: #( Gaol onState )>
   | aGoal |
   aGoal := self copy.
   ^ self onState: (aState pushGoal: aGoal) afterPushingGoal: aGoal
"Fresh, protocol running"
onState: aState

   ^ aState collectVars: receiver argumentNames forFresh: self
"Fresh, protocol dispatched"
onState: aState withVars: aCollection

   variables := aCollection.
   nestedGoal := receiver valueWithArguments: self variables.
   ^ super onState: aState
"Eta, protocol running"
onState: aState

   ^ [ 
     nestedGoal := receiver value.
     super onState: aState ]

onState:afterPushingGoal: message

"Goal, protocol as yet unclassified"
onState: aState afterPushingGoal: aGoal

   self subclassResponsibility
param State aState

a state containing a substitution that makes the top goal true.

return

a stream of exactly one state, namely aState.

rtype

Srfi41Stream

The invariant that governs me can be stated as follows:

SBRAL new asState in: [:s | (true asGoal onState: s) car == s ] >>> true

or even better with the test case

"GoalTest, protocol tests"
testSucceedInvariant

   SBRAL new asState in: [ :s | 
      | ss |
      ss := true asGoal onState: s.
      self assert: ss car equals: s ].
   SBRAL new asState in: [ :s | 
      | ss |
      ss := s srfi41Singleton
               zip: (true asGoal onState: s)
               with: [ :a :b | a == b ].
      self assert: ss equals: { true } modulo: #asOrderedCollection ]
"Disj, protocol running"
onState: aState afterPushingGoal: _

   | aStream anotherStream |
   aStream := left onState: aState.
   anotherStream := right onState: aState.
   ^ aStream appendStream: anotherStream
"Conj, protocol running"
onState: aState afterPushingGoal: _

   ^ (left onState: aState) appendMap: [ :refinedState | 
        refinedState path value in: [ :aGoal | 
           aGoal onState: refinedState forGoal: right fromConj: self ] ]
"Goal, protocol as yet unclassified"
onState: refinedState forGoal: aGoal fromConj: aConj

   self popGoalFromPathOfState: refinedState forConj: aConj. "this message should be removed to be full explicit."
   ^ aGoal onState: refinedState
"Goal, protocol as yet unclassified"
popGoalFromPathOfState: aState forConj: aGoal

   "No action for the generic goal because if I am the top of `aState`'s goal path,
    I have to remain there with respect to the computation running in the
    conjunction goal `aGoal`."

   
"Succeed, protocol as yet unclassified"
popGoalFromPathOfState: aState forConj: aGoal

   aState path: aState path nextLink

Note

This is the sole message that perform a side-effect on the state of an object without creating a new copy of it.

"Failed, protocol as yet unclassified"
onState: refinedState forGoal: right fromConj: aConj

   ^ ValueLink value: refinedState
"Unify, protocol running"
onState: aState afterPushingGoal: aGoal

   | aStateOrException |
   aStateOrException := [ :k | 
                        aState unifier
                           continuation: k;
                           value: left value: right ] valueWithExitUnary.
   ^ aStateOrException onState: aState afterUnificationByUnify: self
"Cond, protocol running"
onState: aState afterPushingGoal: _

   ^ [ 
     | g |
     g := clauses foldr: if init: false asGoal.
     g onState: aState ]
"IfPure, protocol running"
onState: aState afterPushingGoal: _

   | disj |
   disj := chainCombinationStrategy value
              left: question , answer;
              right: otherwise;
              yourself.

   ^ disj onState: aState
"Suspended, protocol as yet unclassified"
onState: aState afterPushingGoal: _

   ^ [ nestedGoal onState: aState ]

walk: message

"State, protocol as yet unclassified"
walk: anObj

   ^ substitution walk: anObj fromState: self