Prolog 序言:read谓词省略了用户输入中的一些括号

Prolog 序言:read谓词省略了用户输入中的一些括号,prolog,Prolog,我不熟悉Prolog。我试图解决一个数字链接难题,不同的电路板大小和连接点的起始和结束位置。由于电路板配置细节各不相同,我从用户那里获得了所有这些细节。为了获得用户输入,我在prolog中使用read/1谓词。但当我再次尝试编写用户输入时,我发现缺少一些括号,这对我进一步处理很重要。下面是我使用的示例代码以及输入和输出 number_link_puzzle(Input):- read(Input), write(Input). 这里的输入值是:7,5,(1:(5,2),(4,3)),(2:(3

我不熟悉Prolog。我试图解决一个数字链接难题,不同的电路板大小和连接点的起始和结束位置。由于电路板配置细节各不相同,我从用户那里获得了所有这些细节。为了获得用户输入,我在prolog中使用read/1谓词。但当我再次尝试编写用户输入时,我发现缺少一些括号,这对我进一步处理很重要。下面是我使用的示例代码以及输入和输出

number_link_puzzle(Input):-
read(Input),
write(Input).
这里的输入值是:7,5,(1:(5,2),(4,3)),(2:(3,2),(4,3))。
注意(4,3)坐标周围的括号。 但是当我写回用户输入时得到的输出是X=(7,5,(1:(5,2),4,3),2:(3,2),4,3)

其中,4,3没有用括号括起来。由于输入中的括号对于我在程序中的进一步处理很重要,我想知道为什么省略这个括号,或者是否有其他方法可以用来完成这一点


提前感谢:)

建议1:强制用户编写有效的Prolog术语,并从顶层以查询方式运行程序。它可能是这样的:

?- number_link_puzzle(puzzle(7, 5, x(1, 5-2, 4-3), x(2, 3-2, 4-3))).
number_link_puzzle(puzzle(A, B, x(C, D-E, F-G), x(H, I-J, K-L)))
我不知道这是什么谜题(因为你没有说),所以我不知道这是否是最好的写作方式。但至少现在您可以在头部使用模式匹配来“提取”(或者说只是访问)所有值。谓词的开头如下所示:

?- number_link_puzzle(puzzle(7, 5, x(1, 5-2, 4-3), x(2, 3-2, 4-3))).
number_link_puzzle(puzzle(A, B, x(C, D-E, F-G), x(H, I-J, K-L)))
在这里输入一些工作代码,让我们将其中的所有变量打印出来:

number_link_puzzle(puzzle(A, B, x(C, D-E, F-G), x(H, I-J, K-L))) :-
    format("~w", [[A,B,C,D,E,F,G,H,I,J,K,L]]).
通过上面的查询,您将得到:

?- number_link_puzzle(puzzle(7, 5, x(1, 5-2, 4-3), x(2, 3-2, 4-3))).
[7,5,1,5,2,4,3,2,3,2,4,3]
true.
这是处理此类问题的一种简单方法:避免问题。建议2和3涉及不必要的工作,我不会编写完全有效的代码

建议2:您可以使用
read/1
,但要更改表示形式,使其成为有效的序言术语。没有必要,因为这只是实施建议1的一种迂回方式

建议3:使用类似于
read_line_to_code
的方法读取代码列表(或字符列表)的所有输入,然后使用DCG对其进行解析。这意味着您可以提出任何您想要的表示,但是您必须解析它以从中提取数据

大致如下:

puzzle(p(A, B, C, D)) -->
    number(A), ", ",
    number(B), ", ",
    x(C), ", ",
    x(D).

x(x(A, B-C, D-E)) -->
    "(", number(A), ": ",
    pair(B, C), ", ",
    pair(D, E), ")".

pair(A, B) --> "(", number(A), ",", number(B), ")".
如果您有SWI Prolog并添加了

:- use_module(library(dcg/basics)).
最重要的是

?- phrase(puzzle(P), `7, 5, (1: (5,2), (4,3)), (2: (3,2), (4,3))`).
P = p(7, 5, x(1, 5-2, 4-3), x(2, 3-2, 4-3)).

read/1
读取序言术语。在这种情况下,括号对Prolog都是有意义的,因此Prolog可以自由地操作它们,因为它希望维护Prolog解析这些术语的方式。在这种情况下,逗号在Prolog中是右关联的,因此对于Prolog而言,
(4,3)
中的括号显得多余,因此在写出术语时不包括它们。如果需要以自己的方式解释每个标记,则需要将输入读取为字符串并对其进行解析。或者,只要编写谓词,就知道Prolog是这样解释逗号的。