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 ] >>> trueor 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 nextLinkNote
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