我是PROLOG的新手,难以达到很少的任务。如果有人能在这方面帮助我,那可能会很棒。所以这就是这个想法:
我有一个包含[3413242341]
的数字列表,目标是简化此列表,直到我可以有一个空列表[]
。 (数字简化技术)。我把目标搞得如下:
我正在为这个项目奋斗两天,任何帮助都会受到高度关注。
答案 0 :(得分:0)
prolog的重要之处在于它是一个声明性语言:你用谓词演算来描述解决方案,并让prolog推理引擎找出解决方案。通常,prolog程序看起来很像问题陈述。我们先来吧?
您的问题陈述描述了2个特定规则,并且(恕我直言)有第3个隐含规则:
[1,2,2,3]
→[1,3]
)。[8,5,4,5,9]
→[8,4,5,4,9]
)。这会建议一个像这样的解决方案:
reduce( [] , [] ). % When the source list is exhausted, we're done.
reduce( [N,N|Ns] , Rs ) :- reduce(Ns,Rs) . % Apply Rule #1
reduce( [N,Q,N|Ns] , [Q,N,Q|Rs] ) :- Q =:= N-1 , reduce(Ns,Rs) . % Apply Rule #2
reduce( [N|Ns] , [N|Rs] ) :- reduce(Ns,Rs) . % Apply Rule #3: (implied)
我当然不知道这是否符合您的要求。另一种方法可能是这样的:
reduce( [] ) . % The empty list is the desired state
reduce( [N|Ns] ) :- % otherwise ...
remove_pairs(Ns,T1) , % - apply rule #1 to the entire list
do_swaps(T2,T3) , % - apply rule #2 to the entire list
T3 \= [N|Ns] , % - if something changed
reduce( T3 ) % - repeat the exercise with the changed list
. % Easy!
%
% apply Rule #1 to the entire list:
% Remove adjacent pairs such that [1,2,2,3] -> [1,3]
%
remove_pairs( [] , [] ) .
remove_pairs( [X] , [X] ) .
remove_pairs( [X,X|Xs] , Rs ) :- remove_pairs(Ns,Rs) .
remove_pairs( [X,Y|Xs] , [X|Rs] ) :- X \= Y , remove_pairs(Xs,Rs) .
%
% Apply Rule #2 to the entire list:
% Swap N,Q,N where Q is N-1 such that [8,5,4,5,9] -> [8,4,5,4,9]
%
do_swaps( [] , [] ) .
do_swaps( [N] , [N] ) .
do_swaps( [N,Q] , [N,Q] ) .
do_swaps( [N,Q,N|Ns] , [Q,N,Q|Rs] ) :- Q =:= N-1 , do_swaps(Ns,Rs) .
do_swaps( [N,Q,N|Ns] , [N,Q,N|Rs] ) :- Q =\= N-1 , do_swaps(Ns,Rs) .
这会将每个转换应用于整个列表。如果列表发生了更改,我们会递归应用reduce/1
操作,如果列表最终转换为空列表[]
,则该操作将成功,并且当转换未能进行任何更改时最终会失败。
当回溯时,它会尝试寻找另一种解决方案。
答案 1 :(得分:0)
解决这个问题的另一种方法:
simplify(In, Lst) :-
simplify(In, [], [], Lst).
simplify([], _Deja_vu, RL, L) :- !, reverse(RL, L).
simplify(In, Deja_vu, Cur, Lst) :-
( r1(In, Out), L =r1; r2(In, Out), L = r2; r3(In, Out), L=r3),
% we must avoid cycles
\+member(Out, Deja_vu),
simplify(Out, [Out| Deja_vu],[L|Cur], Lst).
% If two adjacent numbers are equal, program should remove both of them.
r1(In, Out) :-
append(L, [X,X|T], In),
append(L, T, Out).
% switch between two adjacent digits if the absolute value of
% their difference is greater than 1.
r2(In, Out) :-
append(L, [X,Y|T], In),
abs(X-Y) > 1,
append(L, [Y,X|T], Out).
% (n, n-1, n) sequence must be able to be replaced by the (n-1, n, n-1) sequence.
r3(In, Out) :-
append(L, [X,Y, X|T], In),
X =:= Y+1,
append(L, [Y,X,Y|T], Out).