首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >差异yap和swi-prolog读取规范列表

差异yap和swi-prolog读取规范列表
EN

Stack Overflow用户
提问于 2018-06-19 11:47:54
回答 3查看 189关注 0票数 4

下面的测试代码试图将文件读入列表

代码语言:javascript
复制
open('raw250-split1.pl', read, Stream),
read(Stream,train_xs(TrainXs)),
length(TrainXs, MaxTrain).

由于文件相当大,我将省略部分输出。

它与yap很好地合作,

代码语言:javascript
复制
➜  chill git:(master) ✗ yap                                                      [18/06/19| 5:48PM]
% Restoring file /usr/lib/Yap/startup.yss
YAP 6.2.2 (x86_64-linux): Sat Sep 17 13:59:03 UTC 2016
   ?- open('raw250-split1.pl', read, Stream),                                                           
      read(Stream, train_xs(TrainXs)),                                                                     
      length(TrainXs, MaxTrain).
MaxTrain = 225,
Stream = '$stream'(3),
TrainXs = [[parse([which,rivers,run,through,states,bordering,new,mexico,/],answer(_A,(river(_A),traverse(_A,_B),next_to(_B,_C),const(_C,stateid('new mexico')))))],
<omited output>
,[parse([what,is,the,largest,state,capital,in,population,?],answer(_ST,largest(_SU,(capital(_ST),population(_ST,_SU)))))]]

但是在swi-prolog上,它将产生Type error

代码语言:javascript
复制
➜  chill git:(master) ✗ swipl                                                     [18/06/19| 7:24PM]
Welcome to SWI-Prolog (threaded, 64 bits, version 7.6.4)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit http://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- open('raw250-split1.pl', read, Stream),    
   read(Stream, train_xs(TrainXs)),                                                                     
   length(TrainXs, MaxTrain).
ERROR: raw250-split1.pl:4:
    Type error: `list' expected, found `parse(which.(rivers.(run.(through.(states.(bordering.(new.(mexico.((/).[])))))))),
    <omited output>
,answer(_67604,(state(_67604),next_to(_67604,_67628),const(_67628,stateid(kentucky))))).[].(parse(what.((is).(the.(largest.(state.(capital.(in.(population.((?).[])))))))),answer(_67714,largest(_67720,(capital(_67714),population(_67714,_67720))))).[].[]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))' (a compound)
    In:
      [10] throw(error(type_error(list,...),context(...,_67800)))
       [7] <user>

    Note: some frames are missing due to last-call optimization.
    Re-run your program in debug mode (:- debug.) to get more detail.

这里的错误可能是什么问题?

raw250-split1.pl文件可以从下面的ftp url中找到,如果您想尝试的话。

谢谢你的帮助!

我正在尝试将早期的代码迁移到SWI-Prolog__,它是用SICStus 3 #3: Thu Sep 12 09:54:27 CDT 1996编写的,或者更早由RaymondJ.Mooney ftp://ftp.cs.utexas.edu/pub/mooney/chill/编写的。所有带有这个标签的问题都与这个任务有关。我是prolog的新手,欢迎您的帮助和建议!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-06-19 13:02:38

raw250-split1.pl显然是用规范符号编写的。传统的列表函式是./2,但SWI-Prolog7.x将其改为'[|]'/2,以便将./2用于其他目的。这将导致变量TrainXsread/2调用实例化为一个复合术语,其参数不是(一个列表):

代码语言:javascript
复制
?- open('raw250-split1.pl', read, Stream), read(Stream,train_xs(TrainXs)).
Stream = <stream>(0x7f8975e08e90),
TrainXs = parse(which.(rivers.(run.(through.(states.(bordering.(... . ...)))))), answer(_94,  (river(_94), traverse(_94, _100), next_to(_100, _106), const(_106, stateid('new mexico'))))).[].(parse(what.((is).(the.(highest.(point.(... . ...))))), answer(_206,  (high_point(_204, _206), const(_204, stateid(montana))))).[].(parse(what.((is).(the.(most.(... . ...)))), answer(_298, largest(_300,  (population(_298, _300), state(...), ..., ...)))).[].(parse(through.(which.(states.(... . ...))), answer(_414,  (state(_414), const(..., ...), traverse(..., ...)))).[].(parse(what.((is).(... . ...)), answer(_500, longest(_500, river(...)))).[].(parse(how.(... . ...), answer(_566,  (..., ...))).[].(parse(... . ..., answer(..., ...)).[].(parse(..., ...).[].(... . ... .(... . ...))))))))).

YAP仍然对列表使用./2函子,这解释了为什么它能够处理它。SWI的一个解决方法是使用--traditional命令行选项启动它:

代码语言:javascript
复制
$ swipl --traditional
...
?- open('raw250-split1.pl', read, Stream), read(Stream,train_xs(TrainXs)).
Stream = <stream>(0x7faeb2f77700),
TrainXs = [[parse([which, rivers, run, through, states, bordering|...], answer(_94,  (river(_94), traverse(_94, _100), next_to(_100, _106), const(_106, stateid('new mexico')))))], [parse([what, is, the, highest, point|...], answer(_206,  (high_point(_204, _206), const(_204, stateid(montana)))))], [parse([what, is, the, most|...], answer(_298, largest(_300,  (population(_298, _300), state(...), ..., ...))))], [parse([through, which, states|...], answer(_414,  (state(_414), const(..., ...), traverse(..., ...))))], [parse([what, is|...], answer(_500, longest(_500, river(...))))], [parse([how|...], answer(_566,  (..., ...)))], [parse([...|...], answer(..., ...))], [parse(..., ...)], [...]|...].

您得到的类型错误是由于length/2在绑定第一个参数时期望一个列表。

票数 4
EN

Stack Overflow用户

发布于 2018-06-19 12:49:17

该文件中有一个倾斜字符作为最后一个字符,这会导致语法无效,因此您应该在读取之前删除它。我不知道为什么YAP接受该文件为有效,应该引发AFAIK错误。

票数 1
EN

Stack Overflow用户

发布于 2019-02-14 22:49:19

SWI中有一个读选项dotlist/2:

dotlists(Bool) 如果为true (默认为false),则将.(a,[])读入列表,即使列表是内部的,也不是使用点作为函子构造的。这主要是为了读取来自其他Prolog系统的write_canonical/1的输出。见5.1节。任期/2

这将给出所需的结果,而无需更改模式:

代码语言:javascript
复制
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.0)

?- read_term(X, [dotlists(true)]).
|: .(a,.(b,.(c,[]))).
X = [a, b, c].
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50927685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档