different(Xs, Ys) :-
member(X, Xs),
non_member(X, Ys).
different(Xs, Ys) :-
member(Y, Ys),
non_member(Y, Xs).
Run Code Online (Sandbox Code Playgroud)
虽然这个定义使用member/2和non_member/2几乎是1从声明的观点完美的,它产生于特定查询的冗余解决方案,并选择留点周围.
什么是改进的定义(以纯粹的方式可能使用if_/3和(=)/3),使得完全相同的解决方案集被描述different/2但至少对于地面查询是确定的(因此不会留下任何无用的选择点)并且省略(如有可能)任何多余的答案?
1
实际上,different([a|nonlist],[]), different([],[b|nonlist])成功了.它同样可能失败.所以两者都失败的解决方案很好(甚至可能更精细).
我最近开始学习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)
有人可以帮我吗?
我正在解析一个由一系列行组成的相当简单的文件格式,每行都有一些空格分隔的字段,如下所示:
l 0x9823 1
s 0x1111 3
l 0x1111 12
?
Run Code Online (Sandbox Code Playgroud)
我正在使用SWI-Prolog.这是我到目前为止的DCG:
:- consult(library(pure_input)).
load_trace(Filename, Traces) :-
phrase_from_file(trace_file_phrase(Traces), Filename).
trace_file_phrase([]) --> [].
trace_file_phrase([T|Ts]) --> trace_phrase(T), trace_file_phrase(Ts).
trace_phrase(access(Type, Address, SinceLast)) -->
access_type(Type), space,
address(Address), space,
nat(SinceLast), newline.
access_type(load) --> "l".
access_type(store) --> "s".
address(Number) --> "0x", hexnum(Number).
hexdigit(N) --> digit(N).
hexdigit(10) --> "a". hexdigit(11) --> "b". hexdigit(12) --> "c".
hexdigit(13) --> "d". hexdigit(14) --> "e". hexdigit(15) --> "f".
hexnum(N) --> hexdigit(D), hexnum(D, N).
hexnum(N, N) --> [].
hexnum(A, N) --> hexdigit(D), …Run Code Online (Sandbox Code Playgroud) 我想定义一个成员谓词.
成员(A,B)表示列表A的所有成员都是列表B的成员.top(N)定义A可以有多长.
这是我的尝试:
top(5).
members([X], L):-
member(X, L).
members([X| Xs], L):-
member(X, L),
members(Xs, L),
length(Xs, M),
top(N),
M < N.
Run Code Online (Sandbox Code Playgroud)
我想用它如下:
members(L, [1,2,3]).
Run Code Online (Sandbox Code Playgroud)
我的实施问题是,如果我; 为了得到新的答案,我将以错误结束:超出本地堆栈
?- members(I, [1,2,3]).
I = [1] ;
I = [2] ;
I = [3] ;
I = [1, 1] ;
I = [1, 2] ;
I = [1, 3] ;
I = [1, 1, 1] ;
I = [1, 1, 2] ;
I = [1, 1, 3] ;
I = [1, 1, 1, 1] …Run Code Online (Sandbox Code Playgroud) 我对一个问题的两个解决方案之间的区别有疑问.该问题要求将列表转换为截断列表,如下所示:
?- reduce([a,a,a,b,b,c,c,b,b,d,d],Z).
Z = [a,b,c,b,d].
Run Code Online (Sandbox Code Playgroud)
第一个解决方案需要一个额外的步骤来反转列表:
reduce([X|Xs],Z) :-
reduce(X,Xs,Y,[X]),
reverse(Y,Z).
reduce(X,[L|Ls],Y,List) :-
( X=L
-> reduce(X,Ls,Y,List)
; reduce(L,Ls,Y,[L|List])
).
reduce(_,[],Y,Y).
Run Code Online (Sandbox Code Playgroud)
第二种解决方案不需要reverse/2:
reduced([X|Xs],Result) :-
reduced(Xs,List),
List=[A|_],
( A=X
-> Result=List
; Result=[X|List]
),
!.
reduced(Result,Result).
Run Code Online (Sandbox Code Playgroud)
在一系列语句之前或之后执行递归时有哪些优化注意事项?条件的顺序是否重要?我倾向于认为提前完成所有递归是要走的路,特别是因为这里需要向后构建列表.