标签: prolog-toplevel

为什么这个prolog查询既真实又错误?

我的SWI-Prolog知识库包含以下两个事实:

f(a,b).
f(a,c).
Run Code Online (Sandbox Code Playgroud)

现在,如果我提出查询

?- f(a,c).
true.
Run Code Online (Sandbox Code Playgroud)

?- f(a,b).
true ;
false.
Run Code Online (Sandbox Code Playgroud)

为什么f(a,b)既真又假?当KB中有三个事实时,也会发生这种情况.如果我追加f(a,d).到KB,然后f(a,d)为真(仅),但f(a,b)和f(a,c)都是真和假.发生了什么,我能做些什么让Prolog回答(仅)回答这些问题?

prolog swi-prolog prolog-toplevel

30
推荐指数
2
解决办法
1万
查看次数

自反传递闭包的定义

许多谓词基本上使用某种形式的传递闭包,只是发现终止也必须得到解决.为什么不一次解决这个问题closure0/3:

:- meta_predicate closure0(2,?,?).
:- meta_predicate closure(2,?,?).

:- meta_predicate closure0(2,?,?,+). % internal

closure0(R_2, X0,X) :-
   closure0(R_2, X0,X, [X0]).

closure(R_2, X0,X) :-
   call(R_2, X0,X1),
   closure0(R_2, X1,X, [X1,X0]).

closure0(_R_2, X,X, _).
closure0(R_2, X0,X, Xs) :-
   call(R_2, X0,X1),
   non_member(X1, Xs),
   closure0(R_2, X1,X, [X1|Xs]).

non_member(_E, []).
non_member(E, [X|Xs]) :-
   dif(E,X),
   non_member(E, Xs).
Run Code Online (Sandbox Code Playgroud)

是否存在此定义不能用于实现传递闭包的情况?


为什么dif/2?

详细回答@ WouterBeek的评论:dif/2或者iso_dif/2是理想的,因为它们能够显示或发出潜在问题的信号.但是,在当前的实现中,顶级循环通常会隐藏实际问题.考虑一下closure0(\_^_^true,a,b)本身肯定存在问题的目标.使用以下系统时,实际问题直接不可见.

| ?- closure0(\_^_^true,a,b). % SICStus
yes

?- closure0(\_^_^true,a,b).   % SWI
true ;
true ;
true ...
Run Code Online (Sandbox Code Playgroud)

两个顶级循环都没有显示我们真正想要看到的内容:悬空约束.在SICStus中,我们需要一个伪变量来产生一些替换,在SWI中,查询必须被包装call_residue_vars/2.以这种方式,现在显示所有附加约束的变量.

| …
Run Code Online (Sandbox Code Playgroud)

prolog transitive-closure prolog-toplevel meta-predicate

22
推荐指数
1
解决办法
2976
查看次数

SWI-Prolog - 显示长名单

我正在使用SWI-Prolog并且我正在尝试打印列表,但如果列表中有超过9个项目 - 它看起来像那样 -

[1, 15, 8, 22, 5, 19, 12, 25, 3|...] 
Run Code Online (Sandbox Code Playgroud)

有没有办法显示整个列表?

prolog swi-prolog prolog-toplevel

20
推荐指数
2
解决办法
2万
查看次数

在Prolog中实现"最后"

我试图通过阅读Ulle Endriss的讲义来了解Prolog编程.当我对练习的解决方案没有达到预期的效果时,我发现很难给出一个很好的解释.我认为这与我对Prolog评估表达式的方式的不稳定理解有关.

第20页的练习2.6调用谓词的递归实现,该谓词的last1行为类似于内置谓词last.我的尝试如下:

last1([_ | Rest], Last) :- last1(Rest, Last).
last1([Last], Last).
Run Code Online (Sandbox Code Playgroud)

它给出了正确的答案,但对于具有多个元素的列表,我必须键入分号才能终止查询.这last1与内置的不同last.

?- last1([1], Last).
Last = 1.

?- last1([1, 2], Last).
Last = 2 ;
false.
Run Code Online (Sandbox Code Playgroud)

如果我切换我声明规则和事实的顺序,那么我需要在两种情况下键入分号.

我想我知道为什么Prolog认为last1可能还有一个解决方案(因此是分号).我想它遵循评估顺序

last1([1, 2], Last).
==>  last1([2], Last).
==>  last1([], Last).    OR    Last = 2.
==>  false    OR    Last = 2.
Run Code Online (Sandbox Code Playgroud)

这似乎表明我应该寻找一种方法来避免匹配Rest[].无论如何,我没有解释为什么切换声明的顺序应该有任何影响.

问题1: 对行为的正确解释是last1什么?

问题2: 如何实现last1与内置无法区分的谓词last

list prolog prolog-toplevel

14
推荐指数
2
解决办法
8548
查看次数

Prolog在尝试使用时给出错误"未定义的过程": -

我在Windows上使用SWI-Prolog并收到以下错误:

14 ?- parent(X, Y) :- child(Y, X).
ERROR: toplevel: Undefined procedure: (:-)/2 (DWIM could not correct)
Run Code Online (Sandbox Code Playgroud)

我不完全确定发生了什么,因为这上周工作,我刚开始学习Prolog.

prolog prolog-toplevel

13
推荐指数
2
解决办法
3万
查看次数

Prolog匿名变量

以下是我对Prolog变量的理解.

  1. 单个下划线代表匿名变量,每次发生时都像一个新变量.

  2. 以_W这样的下划线开头的变量名不是匿名变量.或者,Prolog内部生成的变量名称(如_G189)不被视为匿名:

?- append([1,2],X,Y).
X = _G189
Y = [1, 2|_G189]
Run Code Online (Sandbox Code Playgroud)

你能帮我理解一下吗?

顺便说一下,我从一些教程中得到了上面的例子,但是当我在SWI-Prolog版本6中运行它时,我得到以下内容:

?- append([1,2],X,Y).
Y = [1, 2|X].
Run Code Online (Sandbox Code Playgroud)

感谢您.

prolog prolog-toplevel

13
推荐指数
1
解决办法
8146
查看次数

Prolog:制作打印Hello World的程序

我想将这个简单的东西加载到我的编辑器中:

Write:-repeat,write("hi"),nl,fail.
Run Code Online (Sandbox Code Playgroud)

所以它打印"hi".

我该怎么办?

我现在正在尝试做 File->New

并保存名为Write的文件 E:\Program Files\pl\xpce\prolog\lib

在进行查询时:

?-写.

这是打印:

1 ?- Write.
% ... 1,000,000 ............ 10,000,000 years later
% 
%       >> 42 << (last release gives the question)
Run Code Online (Sandbox Code Playgroud)

为什么?

procedure swi-prolog prolog-toplevel

10
推荐指数
1
解决办法
3万
查看次数

使用手动列表迭代与通过失败递归的优缺点是什么

我一直反对这一点,我无法确定攻击它的方法.以下是处理一些季节事实的两种方法.

我想弄清楚的是,是否使用方法1或方法2,以及每种方法的利弊是什么,特别是大量的事实.

methodone因为事实是可用的,所以似乎很浪费,为什么还要建立一个列表(特别是一个大的列表).如果列表足够大,这也必须有内存含义吗?它没有利用Prolog的自然回溯功能.

methodtwo利用回溯来为我做递归,我猜想会有更多的内存效率,但是通常这样做是不是很好的编程习惯呢?这可以说是更难以理解,可能还有其他副作用吗?

我可以看到的一个问题是每次fail调用时,我们都失去了将任何东西传递回调用谓词的能力,例如.如果是的话methodtwo(SeasonResults),因为我们故意不断地破坏谓词.所以methodtwo需要断言事实来存储状态.

大概(?)方法2会更快,因为它没有(大)列表处理吗?

我可以想象,如果我有一个清单,那么methodone将是要走的路......还是总是如此?在任何情况下都可以将列表声明为事实,methodone然后使用方法二处理它们?完全疯了吗?

但话说回来,我读到断言事实是一项非常"昂贵"的业务,所以列表处理可能是要走的路,即使是大型列表?

有什么想法吗?或者有时候使用一个而不是另一个更好,这取决于(什么)情况?例如.对于内存优化,使用方法2,包括断言事实,以及速度使用方法1?

season(spring).
season(summer).
season(autumn).
season(winter).

 % Season handling
showseason(Season) :-
    atom_length(Season, LenSeason),
    write('Season Length is '), write(LenSeason), nl.

% -------------------------------------------------------------
% Method 1 - Findall facts/iterate through the list and process each
%--------------------------------------------------------------
% Iterate manually through a season list
lenseason([]).
lenseason([Season|MoreSeasons]) :-
    showseason(Season),
    lenseason(MoreSeasons).


% Findall to build a list then iterate until all done
methodone :-
    findall(Season, season(Season), …
Run Code Online (Sandbox Code Playgroud)

prolog prolog-dif prolog-toplevel

8
推荐指数
2
解决办法
2032
查看次数

为什么SWI-Prolog只给我第一个答案?

我是Prolog的新手.我只是想简单的例子来学习.我有.pl这些行的这个文件:

parent(pam,bob).
parent(tom,bob).
parent(tom,lio).
parent(bob,ann).
parent(bob,pat).
parent(pat,jim).
Run Code Online (Sandbox Code Playgroud)

咨询和测试后,它只显示第一个答案.例如:

5 ?- parent(X,Y).
X = pam,
Y = bob .
Run Code Online (Sandbox Code Playgroud)

是不是应该给出满足关系的所有组合parent

有谁知道问题是什么?

prolog prolog-toplevel

8
推荐指数
1
解决办法
2035
查看次数

Prolog nth1匿名变量

我有一个带有整数和匿名变量的List,我试图找到一个特殊值的索引.问题是我用它nth1/3来找到索引Prolog为匿名变量分配值,因此我也找到了索引.

例如: List = [1,\_,1],我想要的结果是X = 1, X = 3nth1(X,List,1),而是说之前,我X = 1, X = 2, X = 3.

prolog prolog-toplevel

8
推荐指数
1
解决办法
235
查看次数