Reputation: 17
I'm trying to generate some latex code with prolog. I'm generating nodes connected by edges with the world they belong to. My code is this:
print_valutations(Stream,Number_of_nodes,[Head|Tail]):-
Number_of_nodes1 is Number_of_nodes+1,
single_valutation(Stream,Number_of_nodes1,Head),
print_valutations(Stream,Number_of_nodes1,Tail).
print_valutations(_,_,_):- !.
single_valutation(Stream,Number_of_nodes,[Head|Tail]):-
write(Stream, "\\node[circle, minimum size=6mm, draw]"),
write(Stream, "[left of= 10mm]"),
write(Stream, "[below of= "),
Number_of_nodes1 is Number_of_nodes-1,
write(Stream,Number_of_nodes1),
write(Stream,"]("),
write(Stream, Number_of_nodes),
write(Stream,"){"),
write(Stream,Head),
writeln(Stream,"};"),
val(Stream,Number_of_nodes,Tail).
single_valutation(_,_,_):- !.
val(Stream,Node,[Head|Tail]):-
display_val(Stream,Node,Head),
val(Stream,Node,Tail).
val(_,_,_):- !.
display_val(Stream,[]) :-
write(Stream,"").
display_val(Stream,Node,[Head|Tail]) :-
write(Stream,"\\draw[->] ("),
write(Stream,Node),
write(Stream,") to ("),
write(Stream,Head),
writeln(Stream,");"),
display_val(Stream,Node,Tail).
prova(FileName):-
open(FileName, write, Stream),
print_valutations(Stream, 100,[[a,[4]],[b,[3]],[c,[1]]]),
close(Stream).
And this code generates the following txt file:
\node[circle, minimum size=6mm, draw][left of= 10mm][below of= 100](101){a};
\draw[->] (101) to (4);
\node[circle, minimum size=6mm, draw][left of= 10mm][below of= 101](102){b};
\draw[->] (102) to (3);
\node[circle, minimum size=6mm, draw][left of= 10mm][below of= 102](103){c};
\draw[->] (103) to (1);
What i want is this(leaving left of = 10mm only for the first row):
\node[circle, minimum size=6mm, draw][left of= 10mm][below of= 100](101){a};
\draw[->] (101) to (4);
\node[circle, minimum size=6mm, draw][below of= 101](102){b};
\draw[->] (102) to (3);
\node[circle, minimum size=6mm, draw][below of= 102](103){c};
\draw[->] (103) to (1);
How can i do it?
Upvotes: 0
Views: 83
Reputation: 24976
First off I agree with Paulo that you should use DCGs.
Concept of answer.
One option is to add a guard around
write(Stream, "[left of= 10mm]")
e.g.
(
<guard>
->
write(Stream, "[left of= 10mm]")
;
true
)
See: Predicate ->/2
The guard needs to check when processing the first item in the list.
Working code.
Only the modified code is here. The rest stays the same. It also threw a file error, but I didn't try to find and fix it as I did not modify the file access code. The generated output is below.
print_valutations(Stream,First, Number_of_nodes,[Head|Tail]):-
Number_of_nodes1 is Number_of_nodes+1,
single_valutation(Stream,First,Number_of_nodes1,Head),
print_valutations(Stream,false,Number_of_nodes1,Tail).
print_valutations(_,_,_,_):- !.
single_valutation(Stream,First,Current_node_position,[Head|Tail]):-
write(Stream, "\\node[circle, minimum size=6mm, draw]"),
(
First
->
write(Stream, "[left of= 10mm]")
;
true
),
write(Stream, "[below of= "),
Current_node_position1 is Current_node_position-1,
write(Stream,Current_node_position1),
write(Stream,"]("),
write(Stream, Current_node_position),
write(Stream,"){"),
write(Stream,Head),
writeln(Stream,"};"),
val(Stream,Current_node_position,Tail).
single_valutation(_,_,_,_):- !.
prova(FileName):-
open(FileName, write, Stream),
print_valutations(Stream, true, 100, [[a,[4]],[b,[3]],[c,[1]]]),
close(Stream).
Output
\node[circle, minimum size=6mm, draw][left of= 10mm][below of= 100](101){a};
\draw[->] (101) to (4);
\node[circle, minimum size=6mm, draw][below of= 101](102){b};
\draw[->] (102) to (3);
\node[circle, minimum size=6mm, draw][below of= 102](103){c};
\draw[->] (103) to (1);
Upvotes: 1