小编rep*_*eat的帖子

Prolog:替换指定索引处的列表中的元素

我想要一个Prolog谓词,它可以替换指定索引处的列表中的元素.

例:

% replace(+List,+Index,+Value,-NewList).
?- L=[a,b,c,d], replace(L,1,z,L2).
L2 = [a,z,c,d]
Run Code Online (Sandbox Code Playgroud)

我不知道该怎么做.谢谢你的帮助!卢瓦克.

list prolog

16
推荐指数
3
解决办法
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中列表的连接

有人可以帮助在此规则中找到错误吗?

concat([], List, List).
concat([Head|[]], List, [Head|List]).
concat([Head|Tail], List, Concat) :- concat(Tail, List, C), concat(Head, C, Concat).
Run Code Online (Sandbox Code Playgroud)

尝试连接2个列表失败:

| ?- concat([1,2], [4,7,0], What).

no
Run Code Online (Sandbox Code Playgroud)

list prolog

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

列表中的数字小于给定数字

xMenores(_,[],[]).
xMenores(X,[H|T],[R|Z]) :-
   xMenores(X,T,Z),
   X > H,
   R is H.
Run Code Online (Sandbox Code Playgroud)

xMenores 有三个参数:

  • 第一个是数字.
  • 第二个是数字列表.
  • 第三个是列表,是包含结果的变量.

该规则的目标xMenores是获得一个列表,其中列表的编号(第二个参数)小于第一个参数的值.例如:

?- xMenores(3,[1,2,3],X).
X = [1,2].                        % expected result
Run Code Online (Sandbox Code Playgroud)

问题是xMenores返回falseX > H是假的,我的编程技巧在prolog几乎为空.所以:

?- xMenores(4,[1,2,3],X).
X = [1,2,3].                      % Perfect.

?- xMenores(2,[1,2,3],X).
false.                            % Wrong! "X = [1]" would be perfect.
Run Code Online (Sandbox Code Playgroud)

我认为X > H, R is H.因为我需要的只要X大于H,R取值H.但我不知道像Prolog中的if或者某种控制结构来处理这个问题.

请问,任何解决方案?谢谢.

list prolog

13
推荐指数
5
解决办法
2024
查看次数

Prolog中的逻辑否定

我已经阅读了很多关于Prolog的失败否定的内容,其中Prolog是为了证明\+Goal持有试图证明Goal失败.

这与CWA(近距离世界假设)高度相关,例如,如果我们查询\+P(a)(在哪里P是arity 1的谓词),并且我们没有线索导致证明P(a)Prolog假定(由于CWA)not P(a)如此\+P(a)成功.

从我所搜索的内容来看,这是一种解决经典逻辑弱点的方法,如果我们对此毫无头绪,P(a)那么我们无法回答是否\+P(a)持有.

上面描述的是在Prolog中引入非单调推理的方法.此外,有趣的部分是Clark证明Negation by Failure与经典否定相容/类似仅适用于地面条款.我明白这个例子:

X=1, \+X==1.:应该在Prolog中返回false(在经典逻辑中).

\+X==1, X=1.:应该在经典逻辑中返回false,但是在检查NF的时候它在Prolog中成功,X不受约束,这与classic-Pure Logic不同.

\+X==1.:在X绑定之前,不应该给经典逻辑中的任何答案,但在Prolog中它返回false(可能打破经典逻辑的弱点),这与纯逻辑不相同/兼容.

我的尝试是模拟经典否定,感谢评论中的@false的建议,目前的实施是:

\\+(Goal) :- when(ground(Goal), \+Goal). 
Run Code Online (Sandbox Code Playgroud)

一些测试:

?- \\+(X==1).
when(ground(X), \+X==1).

?- X=1, \\+(X==1).
false.

?- \\+(X==1), X=1.
false. 
Run Code Online (Sandbox Code Playgroud)

我的问题:

以上是对经典否定的正确解释吗?(是否有任何明显的极端情况,它错过了?当使用/ 2时我也关注逻辑纯度,可以安全地假设上面是纯粹的吗??).

prolog negation logical-purity prolog-coroutining

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

排除列表中所有出现的最小数量

作为Prolog新手,我尝试定义一个谓词filter_min/2,该谓词采用两个列表来确定第二个列表是否与第一个列表相同,但是删除了所有出现的最小值.

具有预期结果的示例查询:

?- filter_min([3,2,7,8], N).
N = [3,7,8].

?- filter_min([3,2,7,8], [3,7,8]).
true.
Run Code Online (Sandbox Code Playgroud)

我试过但总是得到相同的结果:false.我不知道问题是什么.我需要帮助!

这是我的代码:

filter_min(X,Y) :-
    X == [],
    write("ERROR: List parameter is empty!"),
    !;
    min_list(X,Z),
    filter(X,Y,Z).

filter([],[],0).
filter([H1|T1],[H2|T2],Z) :-
    \+ number(H1),
    write("ERROR: List parameter contains a non-number element"),
    !;
    H1 \= Z -> H2 is H1, filter(T1,T2,Z);
    filter(T1,T2,Z).
Run Code Online (Sandbox Code Playgroud)

list prolog

12
推荐指数
1
解决办法
373
查看次数

冻结/2 的意外行为

我在玩谓词freeze/2frozen/2

?- freeze(X,a=a), frozen(X,Goal).
?- freeze(X,a=a), freeze(Y,b=b), X=Y, frozen(X,Goal).
Run Code Online (Sandbox Code Playgroud)

(x86_64 的 4.5.1 版)给出了这些答案:

| ?- 冻结(X,a=a),冻结(X,目标)。
目标 = prolog:freeze(X,user:(a=a)) ,
序言:冻结(X,用户:(a = a))?;
不
| ?- 冻结(X,a=a),冻结(Y,b=b),X=Y,冻结(X,目标)。
Y = X,
目标 = (user:(a=a),prolog:freeze(X,user:(b=b))) ,
序言:冻结(X,用户:(a = a)),
序言:冻结(X,用户:(b = b))?;
不

现在没想到!Goal = prolog:freeze(X,user:(a=a))

期望的是像 8.0.3 版给出的答案:

?- 冻结(X,a=a),冻结(X,目标)。
目标 = 用户:(a=a) ,
冻结(X,a = a)。
?- 冻结(X,a=a),冻结(Y,b=b),X=Y,冻结(X,目标)。
X = Y,
目标 = (用户:(a=a), 用户:(b=b)) ,
冻结(Y,a …

prolog sicstus-prolog prolog-coroutining

11
推荐指数
1
解决办法
310
查看次数

简单的prolog程序.获取错误:>/2:参数未充分实例化

余由Prolog的谓词posAt(List1,P,List2),在测试位置是否在元件PList1List2是相等的:

posAt([X|Z], 1, [Y|W]) :-
   X = Y.
posAt([Z|X], K, [W|Y]) :-
   K > 1,
   Kr is K - 1,
   posAt(X, Kr, Y).
Run Code Online (Sandbox Code Playgroud)

测试时:

?- posAt([1,2,3], X, [a,2,b]).
Run Code Online (Sandbox Code Playgroud)

我期望输出,X = 2但我得到以下错误:

ERROR: >/2: Arguments are not sufficiently instantiated

为什么我收到此错误?

list prolog clpfd instantiation-error

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

Prolog性能和递归类型

我正在玩permutation几个程序,并偶然发现了这个小实验:

置换方法1:

permute([], []).
permute([X|Rest], L) :-
    permute(Rest, L1),
    select(X, L, L1).
Run Code Online (Sandbox Code Playgroud)

置换方法2:

permute([], []).
permute(L, [P | P1]) :-
    select(P, L, L1),
    permute(L1, P1).
Run Code Online (Sandbox Code Playgroud)

置换方法3(使用内置):

permute(L, P) :- permutation(L, P).
Run Code Online (Sandbox Code Playgroud)

我知道使用尾递归是一种好习惯,通常使用内置函数应该是有效的.但是当我运行以下内容时:

time(findall(P, permute([1,2,3,4,5,6,7,8,9], P), L)).
Run Code Online (Sandbox Code Playgroud)

我得到了以下结果,这些结果在几次运行中相对一致:

方法1:

% 772,064 inferences, 1.112 CPU in 2.378 seconds (47% CPU, 694451 Lips)
Run Code Online (Sandbox Code Playgroud)

方法2:

% 3,322,118 inferences, 2.126 CPU in 4.660 seconds (46% CPU, 1562923 Lips)
Run Code Online (Sandbox Code Playgroud)

方法3:

% 2,959,245 inferences, 1.967 CPU in 4.217 seconds (47% CPU, 1504539 Lips)
Run Code Online (Sandbox Code Playgroud)

因此,非尾递归方法非常实时有效.

一个特定的递归类型通常更实时有效,所有其他条件相同(我知道这并不总是一个简单的前提)?这个实验告诉我的是,我可能不想总是努力进行尾递归,但我可能需要首先进行性能分析,然后权衡性能优势与尾递归确实具有的其他好处.

performance tail-recursion list permutation prolog

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

以最小开销实现最大Prolog实施的最大数量

这不是关于Prolog代码的直接问题,而是关于安装,管理和更新Prolog实现的问题......

理想情况下,我想在我的机器上拥有的是:

  • 尽可能多的Prolog实现
  • 在任何时候,都应该提供最新的(开发)版本
  • 我可能也希望并排有两个或更多版本(稳定/开发)
  • 安装,管理等的最小开销

我想在我启动机器后选择今天使用的Prolog实现.

我能做什么?有什么在这方面的尝试?我运行Linux.先感谢您!

installation prolog updates

10
推荐指数
0
解决办法
145
查看次数