1

有没有办法知道 Prolog 中的变量是什么类型?我有代码

test:- 
    writeln('Please enter the absolut file name :'),
    read(FileName),
    write('Opening file '),
    write(FileName),nl,
    open(FileName,read,Stream),
    read_file(Stream,Lines),
    close(Stream),
    parseLines(Lines).


% used on reading the text file 
read_file(Stream,[]) :-
    at_end_of_stream(Stream).
% used on reading the text file 
read_file(Stream,[X|L]) :-
    \+ at_end_of_stream(Stream),
    read(Stream,X),
    read_file(Stream,L).

parseLines(Lines):-
%primele 2 linii contin lista cu barbatii si list cu femeile iar 
%restul liniilor contin preferintele acestora
    Lines=[LB|[LF|LPrefs]],
    writeln(LB),
    atom_length(LB,2).

我得到了错误(运行测试时)

ERROR: [Thread pdt_console_client_0_Default Process] atom_length/2: Type error: `list' expected, found `man([m1,m2])'

输入文本文件包含

man = {m1, m2}.
women = {w1, w2}.

m1: w1 > w2.
m2: w1 > w2.
w1: m1 > m2.
w2: m1 > m2.

我正在尝试解析该文件,但是我尝试的任何操作都会收到该错误,例如从文件中读取的 Lines 中的内容不是 string,atoms ,我不知道该怎么做才能解决此问题。

PS关于如何快速/简单地解析文件的任何想法?奇怪的是,解析问题的输入比解决问题要困难得多。

谢谢。

编辑:我找到了复合谓词,从文件中读取的行是复合术语。Edit2:我的目标是读取该文件中的数据并对其进行断言或类似的,我想解决稳定的婚姻问题,我解决了但我无法弄清楚从该文件格式读取输入的这一部分。

Edit3:我有其他输入文件,其中包含以下行:

alan: christine > tina > zoe > ruth > sarah.

由于多个 > 运算符,当尝试将它们作为术语读取时,这条线失败了,所以我认为并不是我的所有输入都是有效的 Prolog

4

1 回答 1

2

由于您标记了您的问题 [swi-prolog],并且您的文件包含有效的 Prolog 术语,您可以使用read_file_to_terms /3,并在一次调用中加载列表(此提示适用于 PS 部分)。之后,您必须处理您的条款列表:您的 parseLines/1 它没用。就像列表处理的示例一样,我将显示每个加载的术语:

?- read_file_to_terms('/home/carlo/x.txt',L,[]), maplist(writeln, L).
man={m1,m2}
women={w1,w2}
m1:w1>w2
m2:w1>w2
w1:m1>m2
w2:m1>m2
L = [man={m1, m2}, women={w1, w2}, m1:w1>w2, m2:w1>w2, w1:m1>m2, w2:m1>m2].

编辑 我认为 {} 被命名为“集合构造函数”,它只是一个奇怪的复合形状:

?- write_canonical({a,b,c}).
{}(','(a,','(b,c)))

您可以使用 univ 获取参数列表

?- {a,b,c} =.. X.
X = [{}, (a, b, c)].

以前编辑中的错误

=..似乎没有什么相关性,因为 {} 不仅仅是一个复合词,它更像一个运算符,包括前缀和后缀(即以某种方式组合op(xf,,({))and op(fx,,(})))。

AFAIK 将“集合”转换为列表需要类似

setcons_to_list(S, L) :-
    S =.. [{}, E] -> andexpr_to_list(E, L) ; L = [].

andexpr_to_list((E,Es), [E|Ts]) :-
    !, andexpr_to_list(Es, Ts).
andexpr_to_list(E, [E]).

测试

?- setcons_to_list({},L).
L = [].

?- setcons_to_list({1,2,3,4},L).
L = [1, 2, 3, 4].

更多编辑

Prolog 运算符是“可配置的”,可以向解析器指示该首选项列表。在源代码中添加op声明:- op(10,xfy,(>)).。这里是使用提示的示例

?- op(10,xfy,(>)).
true.

?- X = (alan: christine > tina > zoe > ruth > sarah),write_canonical(X).
:(alan,>(christine,>(tina,>(zoe,>(ruth,sarah)))))
X = alan:christine>tina>zoe>ruth>sarah.

当心:更改预定义的关联性应该小心。否则,如果您更喜欢使用 DCG 制作更通用的解析器,那么这个其他答案可能会很有用。

于 2013-01-08T16:58:58.173 回答