许多谓词定义了某种通过二元关系定义的边构建的非循环路径,与定义传递闭包非常相似.因此需要通用定义.
请注意,图论中定义的概念不容易与通常预期的匹配.最值得注意的是,我们对边缘的名称不感兴趣.
更糟糕的是,图论也发生了一些变化,引入了步行的概念,注意到了
传统上,路径指的是现在通常称为开放式步行的路径.如今,当没有任何限定地陈述时,路径通常被理解为简单,意味着没有重复顶点(因此没有边缘).(术语链也用于指代所有顶点和边缘都不同的步行.)
所以我的问题是:如何命名和定义此功能?
到目前为止我所做的是定义:
path(Rel_2, Path, X0,X)
Run Code Online (Sandbox Code Playgroud)
第一个论点必须是关系的延续.然后是Path顶点或顶点.
n(a, b).
n(b, c).
n(b, a).
?- path(n,Xs, a,X).
Xs = [a], X = a ;
Xs = [a, b], X = b ;
Xs = [a, b, c], X = c ;
false.
Run Code Online (Sandbox Code Playgroud)
:- meta_predicate path(2,?,?,?).
:- meta_predicate path(2,?,?,?,+).
path(R_2, [X0|Ys], X0,X) :-
path(R_2, Ys, X0,X, [X0]).
path(_R_2, [], X,X, _).
path(R_2, [X1|Ys], X0,X, Xs) :-
call(R_2, X0,X1),
non_member(X1, Xs),
path(R_2, …Run Code Online (Sandbox Code Playgroud) 如何编写map(List, PredName, Result)将谓词应用于PredName(Arg, Res)元素的Prolog过程,并将List结果返回到列表中Result?
例如:
test(N,R) :- R is N*N.
?- map([3,5,-2], test, L).
L = [9,25,4] ;
no
Run Code Online (Sandbox Code Playgroud) 许多谓词基本上使用某种形式的传递闭包,只是发现终止也必须得到解决.为什么不一次解决这个问题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)
是否存在此定义不能用于实现传递闭包的情况?
详细回答@ 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) 在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) 我目前正在开发一个关于Prolog的非常短的项目,并且试图将我创建的"过滤器"应用到列表中.我有你可以称之为过滤器的东西,但我无法应用它.如果我说明一下会更好:
filter(A, B)
Run Code Online (Sandbox Code Playgroud)
...如果满足某些条件,则输出'true'.
filterList(A, [X, Y, Z])
Run Code Online (Sandbox Code Playgroud)
...输出一个列表,其中包含第二个参数中使过滤器输出为false的所有元素.(因此,如果过滤器(A,X)为真,则输出为[Y,Z]).
我已准备好"过滤器"功能,但现在我需要将它应用于第二个示例中所示的列表,排除在应用第一个参数时过滤器返回true的所有元素.
因此,如果过滤器是简单的A == B,则该函数应该接收A [A,B,A,C,D,A]并输出[B,C,D],删除了所有元素显然,过滤器适用.
我在功能的基本结构方面遇到了麻烦,所以如果有人能为这样的功能提供一个基本的轮廓,那将会有很大的帮助.我尽可能地简化了我的情况,所以我可以拿出你能提供的任何东西,并根据我的需要进行修改.
提前致谢!
所以univ运营商.我并不完全理解.
例如:
foo(PredList,[H|_]) :- bar(PredList,H).
foo(PredList,[_|T]) :- foo(PredList,T),!.
bar([H|_],Item) :- G =.. [H,Item],G.
bar([_|T],Item) :- bar(T,Item).
Run Code Online (Sandbox Code Playgroud)
这是做什么的?这样可以查看另一个谓词是否为真.我不明白".."的作用.
如果没有univ运算符,你会如何重写它?
如果给定关系的列表元素的所有对都为真,则以下高阶谓词成功.对于这种关系,是否存在共同的或更好的,更具意图的名称?
我对这个名字的最初动机是,在clpfd中all_different/1,如果元素成对不同,通常会有一个被描述为真的约束.事实上,更倾向于说元素都是不同的,但我经常纠正(由Prolog程序员同意)使用pairwise不同.事实上,这种约束现在最自然地表达为pairwise(#\=, Zs).
pairwise(Rel_2, Xs) :-
i_pairwise(Xs, Rel_2).
i_pairwise([], _).
i_pairwise([X|Xs], Rel_2) :-
maplist(call(Rel_2,X),Xs),
i_pairwise(Xs, Rel_2).
Run Code Online (Sandbox Code Playgroud)
正如@aBathologist所观察到的,成对不是正确的词,因为它也可能对非反身有意义Rel.
此外,关系Rel不是一个完整的关系,因为call(Rel, X, X)可能会失败,但pairwise(Rel, Xs)仍然可以成功.
我甚至还在鼓励(a->a->Bool)->[a]->Bool.但是Hayoo 发现它:名字pairwise与逐点相反.
看MO和数学:
这是一个已经删除的问题答案引发的问题.该问题可归纳如下:
是否可以折叠列表,折叠时生成列表的尾部?
这就是我的意思.假设我想计算阶乘(这是一个愚蠢的例子,但它仅用于演示),并决定这样做:
fac_a(N, F) :-
must_be(nonneg, N),
( N =< 1
-> F = 1
; numlist(2, N, [H|T]),
foldl(multiplication, T, H, F)
).
multiplication(X, Y, Z) :-
Z is Y * X.
Run Code Online (Sandbox Code Playgroud)
在这里,我需要生成我给出的列表foldl.但是,我可以在常量内存中执行相同的操作(不生成列表而不使用foldl):
fac_b(N, F) :-
must_be(nonneg, N),
( N =< 1
-> F = 1
; fac_b_1(2, N, 2, F)
).
fac_b_1(X, N, Acc, F) :-
( X < N
-> succ(X, X1),
Acc1 is X1 * Acc,
fac_b_1(X1, N, Acc1, …Run Code Online (Sandbox Code Playgroud) Hilog术语(即具有作为算子任意术语的化合物)是否仍被视为XSB Prolog(或任何其他Prolog)中的强大功能?目前有许多XSB项目正在使用此功能吗?例如他们中的哪一个?
我问,因为据我所知,高阶编程同样可以使用ISO内置调用/ N.
具体来说,我想了解XSB是否仅仅出于历史原因使用Hilog术语,或者如果Hilog术语与当前的ISO标准相比具有相当大的优势.
我试图定义一个callto_status(Goal, Status)总是成功的关系,并根据调用的结果统一Status Goal(换句话说,我想实现一个改进版本call_with_inference_limit/3).我的实现使用的SWI call_with_inference_limit/3具有相同的接口call_with_time_limit/3(在这种情况下也应该使它工作).实施call_with_..._limit并没有回溯,所以我认为最好不要给人一种报告目标答案替代的印象.
我介绍了辅助谓词derivable_st的可读性.它处理成功和超时的情况,但否则失败.
% if Goal succeeds, succeed with Status = true,
% if Goal times out, succeed with Status = timeout
% if Goal fails, fail
derivable_st(Goal, Status) :-
T = 10000, % set inference limit
% copy_term(Goal, G), % work on a copy of Goal, we don't want to report an answer substitution
call_with_inference_limit(G, T, R), % actual call to set inference limit
( …Run Code Online (Sandbox Code Playgroud) meta-predicate ×10
prolog ×10
backtracking ×1
clpfd ×1
filter ×1
fold ×1
graph ×1
iso-prolog ×1
list ×1
map-function ×1
swi-prolog ×1
terminology ×1
topology ×1
xsb ×1