This is a short discussion about how to model a flow of data enabling sharing and moving trough the datastructure in a left to right fashion. We ould like to cut out objects and insert them in other places and maintain everything in a prolog like datastructure.
The idea of the basic object is that it has a left neighbour and a right neighbour. We shall therefore model a place as
line(Left,It,Right) this allows for left right traversal and allows tree like behavior. Further more we would like to insert a segment at multiple places. Therefore
Right has a structure e.g.
Left = *; Left = end(List,Right); Left = X;
e.g. the standard way of sayng end of object is
* but if we cut this position and insert it in another place we will need
end(L,B)? whereL` is a list of stop id's and if encounters marks an end of the object. The final clause just means that it will just represent a next object.
A value is marked as
val(X) and means that the object is a leaf and stops the recursion.
So what do we need to traverse and modify this datastructure? AS we move we will need the left backtrack e.g. so that we can move up the tree and to the left. The nomeclaure is to use
L as a place holder for this object. We keep similar track of the right direction.
The check for an end node will be:
% end(Obj,PathToTop) end(*,_) :- !. end(end(List,Right),R) :- member(R,List).
We will in case we insert a segment elsewhere simply adjust the end nodes so that they include the new pathes to simply mark the new end.
we will also ask for a next value in case it is not an end this will be through
% next(Obj,Next) next(*,_) :- !,fail. next(end(_,Next),Next) :- !. next(Next,Next).
Lets get to some of the meat now, take object and lets dive down to a ground element it represent, let's dive:
% dive(Action,Obj,L,R,Result,LL,RR)) % diving down a line action and record a tree path as we go dive(F,line(A,It,B),L,R,Y,LL,RR) :- end(A,L), end(B,R),!, dive(F,It,L,R,Y,LL,RR). dive(F,Obj,L,R,Y,LL,RR) :- Obj=line(A,It,B), end(A,L),!, R2 = [Obj|R], dive(F,It,L,R2,Y,LL,RR). dive(F,Obj,L,R,Y,LL,RR) :- Obj=line(A,It,B), end(B,R),!, L2 = [Obj|L], dive(F,It,L2,R,Y,LL,RR). dive(F,Obj,L,R,Y,LL,RR) :- Obj = line(A,It,B), L2 = [W|L], R2 = [W|R], dive(F,It,L2,R2,Y,LL,RR). % At the leaf we do an action dive(F,Obj,L,R,Y,LL,RR) call(F(Obj,L,R,Y,LL,RR)).
dive will take the direct tree path to a leaf and then issue an action. We can define a few useful actions:
id(W,L,R,W,L,R). nextf(_,L,[line(A,It,B)|R],Y,LL,RR) :- next(B,BB), dive(id,BB,L,R,Y,LL,RR). prevf(_,[line(A,It,B)|L],R,Y,LL,RR) :- next(A,AA), dive(id,AA,L,R,Y,LL,RR).