相关疑难解决方法(0)

术语平等/不平等的具体化

纯粹的Prolog程序以清晰的方式区分术语的平等和不平等,导致执行效率低下; 即使所有相关术语都是基础的.

关于SO的最近一个例子是这个答案.在此定义中,所有答案和所有失败都是正确的.考虑:

?- Es = [E1,E2], occurrences(E, Es, Fs).
Es = Fs, Fs = [E, E],
E1 = E2, E2 = E ;
Es = [E, E2],
E1 = E,
Fs = [E],
dif(E, E2) ;
Es = [E1, E],
E2 = E,
Fs = [E],
dif(E, E1) ;
Es = [E1, E2],
Fs = [],
dif(E, E1),
dif(E, E2).
Run Code Online (Sandbox Code Playgroud)

虽然程序从声明的角度来看是完美无缺的,但它在B,SICStus,SWI,YAP等当前系统上的直接执行效率却不必要地低效.对于以下目标,列表的每个元素保留一个选择点.

?- occurrences(a,[a,a,a,a,a],M).
M = [a, a, a, a, a] ;
false. …

prolog prolog-dif

40
推荐指数
3
解决办法
1328
查看次数

`memberd/2`的更多确定性?

许多系统提供了纯粹而有效的实现member/2.特别是,没有选择点可供选择:

?- member(b,[a,b]).
true.
Run Code Online (Sandbox Code Playgroud)

然而,member/2生产的天真实施相当:

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

从声明的角度来看肯定是正确的,但效率较低.

另一方面,存在一些技术问题member/2.它允许冗余解决方案,如:

?- member(a,[a,a]).
true ;
true.
Run Code Online (Sandbox Code Playgroud)

memberd/2使用if_/3和解决这个问题(=)/3.

memberd(E, [X|Xs]) :-
   if_(E = X, true, memberd(E, Xs)).

?- memberd(a,[a,a]).
true.
Run Code Online (Sandbox Code Playgroud)

不幸的是,这个定义使选择点再次打开 - ; false在成员不这样做的情况下产生("剩余的选择点"):

?- memberd(X,[a,b]).
X = a ;
X = b ;
false.    % BAD - to be avoided!

?- member(X,[a,b]).
X = a ;
X = b.
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:是否有一个定义memberd/2,避免选择点如上所述?

list prolog

27
推荐指数
3
解决办法
358
查看次数

最常见的高阶约束描述了关于关系排序的整数序列

在CLP(FD)中,我们经常需要声明:"这是整数和有限域变量的列表(有时:严格地)升序/降序."

是否有任何CLP(FD)系统为此任务提供通用(参数化)内置约束?

SWI-Prolog提供了一个名为的约束chain/2,类似于我正在寻找的约束.但是,名称稍微过于具体,不能包含约束可以描述的所有关系(例如:#<不是部分顺序,但是可以接受chain/2,导致序列 - 作为一组整数 - 不再计算为链中定义的链数学顺序理论).因此,该名称并未完全描述约束实际实现的内容.

请给所述最一般相对于通常的二进制CLP(FD)约束定义-或包含至少一个合适的子集#<,#>,#=<#>=- 包括根据代数结构的约束定义适当的名称.强加的条件是约束描述了在文献中具有正确名称的实际数学结构.

首先,请考虑使用SICStus Prolog或SWI:

:- use_module(library(clpfd)).

connex(Relation_2, List) :-
    connex_relation(Relation_2),
    connex_(List, Relation_2).

connex_relation(#=).
connex_relation(#<).
connex_relation(#=<).
connex_relation(#>).
connex_relation(#>=).

connex_([], _).
connex_([L|Ls], Relation_2) :-
    foldl(adjacent(Relation_2), Ls, L, _).

adjacent(Relation_2, X, Prev, X) :- call(Relation_2, Prev, X).
Run Code Online (Sandbox Code Playgroud)

示例案例:

?- connex(#<, [A,B,C]).
A#=<B+-1,
B#=<C+-1.

?- connex(#=, [A,B,C]).
A = B, B = C,
C in inf..sup. …
Run Code Online (Sandbox Code Playgroud)

topology prolog clpfd meta-predicate

22
推荐指数
2
解决办法
1114
查看次数

AUBUC的Prolog联盟

我最近开始学习Prolog,我无法解决如何组合三个列表的问题.

我能够组合2个列表:

%element
element(X,[X|_]).
element(X,[_|Y]):-
               element(X,Y).

%union

union([],M,M).
union([X|Y],L,S) :- element(X,L),union(Y,L,S).
union([X|Y],L,[X|S]) :- (not(element(X,L))),union(Y,L,S).
Run Code Online (Sandbox Code Playgroud)

有人可以帮我吗?

list prolog

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

memberchk/2的声明性用法

memberchk/2是一个通常定义的谓词,它是这样定义的member/2:

memberchk(X, Xs) :-
   once(member(X, Xs)).
Run Code Online (Sandbox Code Playgroud)

因此它只能成功地获得第一个答案member/2.它的完整程序意义不适合纯粹的关系.作为其非关系行为的一个例子考虑

?- memberchk(b, [X,b]), X = a.
false.

?- X = a, memberchk(b, [X,b]).
X = a.
Run Code Online (Sandbox Code Playgroud)

另一方面,在许多情况下,memberchk/2将使用充分实例化的参数调用,其中可以将其视为纯关系的有效近似.

背后的一个纯粹的关系是memberd/2(使用if_/3):

memberd(E, [X|Xs]) :-
   if_(E = X, true, memberd(E, Xs) ).
Run Code Online (Sandbox Code Playgroud)

memberchk/2对于充分实例化的案例,是否还有其他可以近似的纯关系?

换句话说:是否是memberd/2一个完整的,声明性的替代品,memberchk/2或者是否仍然存在memberchk/2无法替代的合法案例memberd/2

prolog logical-purity

17
推荐指数
1
解决办法
689
查看次数

gprolog:在异常后获取堆栈跟踪

使用gprolog时,我经常会遇到没有任何类型的行号或上下文的异常:

uncaught exception: error(instantiation_error,(is)/2)
Run Code Online (Sandbox Code Playgroud)

没有任何背景.我知道我可以做一个trace但是调试它需要很长时间,trace因为我需要在到达发生错误的地方之前执行很多事情.

有关如何进行此堆栈跟踪的任何想法?还是一个动态trace/ notrace

编辑:或者只是自动化整个trace输出的打印.

debugging prolog gnu-prolog

9
推荐指数
2
解决办法
866
查看次数

Prolog:第一个重复值

我需要在列表中找到第一个重复值.

prep(3,[1,3,5,3,5]). 应该是真的.

prep(5,[1,3,5,3,5]). 应该是假的.

我想检查与当前值和先前列表成员的相等性,直到我找到重复,如果它找到一个它将测试与X的相等但我不知道如何在Prolog中做到这一点!

我感谢任何帮助!谢谢

list prolog prolog-dif

5
推荐指数
2
解决办法
2907
查看次数

如何实现not_all_equal/1谓词

如何实现not_all_equal/1谓词,如果给定列表包含至少2个不同的元素,则谓词成功,否则失败?

这是我的尝试(不是很纯粹):

not_all_equal(L) :-
    (   member(H1, L), member(H2, L), H1 \= H2 -> true
    ;   list_to_set(L, S),
        not_all_equal_(S)
    ).

not_all_equal_([H|T]) :-
    (   member(H1, T), dif(H, H1)
    ;   not_all_equal_(T)
    ).
Run Code Online (Sandbox Code Playgroud)

然而,这并不总是具有最佳行为:

?- not_all_equal([A,B,C]), A = a, B = b.
A = a,
B = b ;
A = a,
B = b,
dif(a, C) ;
A = a,
B = b,
dif(b, C) ;
false.
Run Code Online (Sandbox Code Playgroud)

在这个例子中,只有第一个答案应该出来,另外两个答案是多余的.

predicate list prolog prolog-dif logical-purity

5
推荐指数
2
解决办法
148
查看次数

在Prolog列表中查找2的幂

我正在尝试在Prolog(SWI Prolog)中创建一个列表,并检查哪些数字是2的幂,然后查找列表中特定数字的次数(在此示例中,我试图查找该数字的次数)列表中有3个).举个例子,如果你问

?- check([0,2,3,-5,-2,1,8,7,4], MULT2, THREE).
Run Code Online (Sandbox Code Playgroud)

你应该看到

MULT2=[2,8,4] 
THREE=1 
Run Code Online (Sandbox Code Playgroud)

我第一次尝试找到一个解决方案是用头部搜索列表并执行头部mod 2 = 0来查找所有2次幂的数字,但是出了点问题我只得到"假"作为答案.

list prolog clpfd clpz

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