Date sön 23 september 2018

Sometimes we don't have currently all information to evaluate an expression, for example in a stream we want to use future values. So it can be nifty to record the evaluation and perform it when values are available. in (logic guile-log guile-prolog delay) we have the tools to do this. The first step is to take an expression and rewrite it for the tool. A variable will have another structure and we will need to insert a value ito this structure outside the normal mechanism for setting a value. so take a normal addition and define

plus0(X,Y,Z) :-
  XX is val(X),
  YY is val(Y),
  ZZ is ZZ + YY,
  insert(ZZ,Z).

Now using this plus0 we can create a delayd plus with

plus(X,Y,Z) :- delay(plus0(X,Y,X),[X,Y]).

The first argument in delay is the action that will be fired when both X and Y has been instantiated. the second argument is a list of all variables that must be nonvariable in order to fire plus0(X,Y,Z). This is how it can behave

prolog> plus(X,Y,Z).
X = <delay>,
Y = <delay>,

Let's afterwards insert the value

prolog> plus(X,Y,Z),insert(1,X),insert(1,Y).
-->
X = 1,
Y = 1,
Z = 2.

We can chain expressions however we like

prolog> plus(Z,X,W),plus(X,Y,Z),insert(1,X),insert(1,Y).
-->
X = 1,
Y = 1,
Z = 2,
W = 2.

Now the next development out of this is to create a trigger network that works like a spreadsheet of cells. This the variables will be translated to cell structures and keep beeing those, and we need to use the val operator to retrieve the value, so here we first define a cell version of plus,

plusc(X,Y,Z) :- cellit(plus0(X,Y,Z),[X,Y]).

and now,

prolog> cell(Z),plusc(X,Y,Z).
-->
X = <cell #>,
Y = <cell #>,
Z = <cell #>.

inserting values lead to

prolog> cell(Z),plusc(X,Y,Z),insert(1,X),insert(1,Y).
-->
X = <cell 1>,
Y = <cell 1>,
Z = <cell 2>.

And it's mutable but backtrackable to put another value in X

prolog> cell(Z),plusc(X,Y,Z),insert(1,X),insert(1,Y),insert(2,X).
-->
X = <cell 2>,
Y = <cell 1>,
Z = <cell 3>.

This means that with this little tool you have something vastly better than a spreadsheet at your prolog and guile-log fingertips. Note that to define a variable a cell variable you do, which is not mandatory in this case, Z could be left as a variable.

cell(Z)

You can initiate it as well

cell(Z,1)

The predicate cellit will automatically make the variable cell variables but not the depedant variable Z. When it creates a value on it it will however create a cell structured variable. We can also do this,

prolog> cell([X,Y]),cell([A,B],[1,2]).
--->
X = <cell #>,
Y = <cell #>,
A = <cell 1>,
B = <cell 2>.

We could prepend to plusc the following clauses,

plusc([],[],[]).
plusc([X|XX],[Y|YY],[Z|ZZ]) :- plusc(X,Y,Z),plusc(XX,YY,XX).

Then we can do,

prolog > cell(X,[1,2,3]),cell(Y,[9,8,7]),plusc(X,Y,Z).
...

Then you will have a normal formula between collumns X,Y,Z just like in a spreadsheet. And then you can manipulate the formula just as you like, store a state, name it, and the continue and later move between them freely in alightweight manner, because you typically will execute a kind of diff between the different states.


Comments

comments powered by Disqus

~ Follow me ~