如何在SWI Prolog中获得术语的类型

时间:2013-01-08 15:08:25

标签: prolog

有没有办法知道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.

我正在尝试解析该文件,但是我尝试的任何东西都会出现错误,就像从文件中读取的行中的东西不是字符串,原子,我不知道该怎么做才能解决这个问题。

P.S.Any关于如何快速/简单地解析文件的想法?令人感到奇怪的是解析问题的输入要比解决问题困难得多。

感谢。

编辑:我发现复合谓词和从文件中读取的行是一个复合词。 EDIT2: 我的目标是读取该文件中的数据并断言它或类似,我想解决稳定的婚姻问题,我解决了它,但我无法弄清楚从这种文件格式读取输入的这一部分。

EDIT3: 我有其他输入文件,其行如:

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

并且当尝试将它们作为带有read_file_to_terms的术语读取时,这些行失败,因为多个>运营商,所以我认为我的所有输入都不是有效的Prolog

1 个答案:

答案 0 :(得分:2)

由于您标记了您的问题[swi-prolog],并且您的文件包含有效的Prolog术语,您可以使用read_file_to_terms / 3,并在一次调用中加载列表(此提示适用于P.S.部分)。之后你必须处理你的条款清单:你的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].

编辑我认为{}被命名为'set constructor',它只是一个奇怪的形状:

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

你可以使用univ来获取参数列表

?- {a,b,c} =.. X.
X = [{}, (a, b, c)].
之前编辑

中的

错误

=..似乎没那么相关,因为不仅仅是一个复合,{}类似于运算符,都是前缀和后缀(即以某种方式组合op(xf,,({))和{{ 1}})。

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

的内容
op(fx,,(}))

测试

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

更多编辑

Prolog运算符是“可配置的”,可以向解析器指示该首选项列表。在您的来源?- setcons_to_list({},L). L = []. ?- setcons_to_list({1,2,3,4},L). L = [1, 2, 3, 4]. 中添加op声明。这里有一个使用提示

的示例
:- op(10,xfy,(>)).
请注意:应谨慎更改预定义的关联性。否则,如果您更喜欢使用DCG制作更通用的解析器,this其他答案可能会有用。