【问题标题】:How to selectively run a goal in a clause如何在子句中选择性地运行目标
【发布时间】:2021-08-02 08:27:30
【问题描述】:

我正在尝试使用 prolog 生成一些乳胶代码。我正在生成通过边缘与它们所属的世界连接的节点。我的代码是这样的:

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).

并且这段代码会生成如下的txt文件:

    \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);

我想要的是这个(仅在第一行留下 = 10mm 的左侧):

    \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);

我该怎么做?

【问题讨论】:

  • DCG 将提供更简单、清晰、优雅的解决方案。

标签: list prolog nested-lists


【解决方案1】:

首先,我同意 Paulo 的观点,即您应该使用 DCG。


答案的概念。

一种选择是在周围添加guard

write(Stream, "[left of= 10mm]")

例如

(
    <guard>
->
   write(Stream, "[left of= 10mm]")
;
   true
)

见:Predicate ->/2

守卫在处理列表中的第一项时需要检查。


工作代码。

这里只有修改过的代码。其余的保持不变。 它也抛出了一个文件错误,但我没有尝试找到并修复它,因为我没有修改文件访问代码。 生成的输出如下。

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).

输出

\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);

【讨论】:

  • 如果我这样做,它不起作用 "(Node_index=101->write(Stream, "[left of= 10mm]");true), "。它打印 \node[circle, minimum size=6mm, draw][below of= 100](101){p}; \draw[->] (101) 到 (2); \draw[->] (101) 到 (1); \node[圆,最小尺寸=6mm,绘制][低于= 101](102){q}; \draw[->] (102) 到 (3); \node[圆,最小尺寸=6mm,绘制][低于= 102](103){r}; \draw[->] (103) 到 (2);
猜你喜欢
  • 2019-05-14
  • 1970-01-01
  • 2019-07-30
  • 2016-12-30
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
相关资源
最近更新 更多