关于装错信封问题的prolog程序,有没有大虾知道哪里错了?
问题描述:
糊涂先生给他的五个朋友写信,他写了五封信,但是当他的朋友收到信后,都告诉他:“你的信寄错了”。那么请你计算一下:出现这种情况的概率有多少?(假设糊涂先生是随机地往信封里装信),你能不能把所有的情况都列出来呢?
domains
a=integer
al=a*
predicates
delete(a,al,al)
permutation(al,al)
some_element_right(al,al)
letter(al,al)
clauses
% delete(A,B,C), B为列表,A为B中的某个元素,C为把B中的元素A除去后的列表。
delete(A,[A|X],X).
delete(A,[B|X],[B|Y]):-
delete(A,X,Y).
% permutation(A,B), 列表A为列表B的全排列之一时,成功。
permutation([],[]).
permutation([A|X],Y):-
delete(A,Y,Y1),
permutation(X,Y1).
% some_element_right(A,B) 如果列表A与B中存在位置相同的元素则成功。
some_element_right([A|X],[A|Y]).
some_element_right([A|X],[B|Y]):-
some_element_right(X,Y).
letter(X,Y):-
permutation(X,Y),
not(some_element_right(X,Y)).
goal
letter(X,[1,2,3,4,5]),write(X),nl,fail.
[解决办法]
我用GNU-Prolog运行了你的程序,程序因overflow退出。
暂时没有时间帮你找错,程序大致是对的,很可能是某些语句顺序不对导致prolog在某处死循环。
概论是44/5!=44/120=11/30.
你可以用我写的如下程序:
p1(X,N) :- length(X,N),
fd_domain(X,1,N),
fd_all_different(X),
fd_labeling(X, [variable_method(ff),value_method(random)]),
wrong(X,1),
write(X),nl,fail.
%the first element does not equal to N, means the corresponding letter is wrong.
wrong([],_). %base condition
wrong([H|T],N) :- H =\= N, N1 is N+1, wrong(T,N1). %recursive body
运行结果如下:
| ?- p1(X,5).
[4,5,1,2,3]
[4,5,1,3,2]
[4,5,2,3,1]
[4,5,2,1,3]
[4,3,5,2,1]
[4,3,5,1,2]
[4,3,1,5,2]
[4,3,2,5,1]
[4,1,2,5,3]
[4,1,5,3,2]
[4,1,5,2,3]
[5,3,2,1,4]
[5,3,1,2,4]
[5,3,4,2,1]
[5,3,4,1,2]
[5,4,1,3,2]
[5,4,1,2,3]
[5,4,2,3,1]
[5,4,2,1,3]
[5,1,2,3,4]
[5,1,4,2,3]
[5,1,4,3,2]
[3,4,5,2,1]
[3,4,5,1,2]
[3,4,1,5,2]
[3,4,2,5,1]
[3,1,2,5,4]
[3,1,5,2,4]
[3,1,4,5,2]
[3,5,4,1,2]
[3,5,4,2,1]
[3,5,2,1,4]
[3,5,1,2,4]
[2,1,5,3,4]
[2,1,4,5,3]
[2,5,4,3,1]
[2,5,4,1,3]
[2,5,1,3,4]
[2,4,1,5,3]
[2,4,5,3,1]
[2,4,5,1,3]
[2,3,4,5,1]
[2,3,1,5,4]
[2,3,5,1,4]
44 results
[解决办法]
我也在学prolog 有机会给我邮件:jamie.xue@gmail.com 共同进步