我正在尝试创建一个坐标列表:
insert(X,L,[X|L]).
% L is a list and Q is a count that define the number of coordinate
% X and Y are the coordinate members
% check if the coordinate already exists
% if exists, R is 0 and if not, R is 1
% if the count is different of 0, I continous generating coordinates, else, I stop
createCoordinates(L,Q) :-
C is Q,
random(1,10,X),
random(1,10,Y),
convertNumber(X,Z),
checkCoordinate([Z,Y],L,R),
(C \== 0 -> (R is 0 -> createCoordinates(L,Q); insert([X,Y],L,A), createCoordinates(A,Q-1)); trace, print(L),print('Done!')).
checkCoordinate(C,L,R) :-
(member(C,L) -> R is 0; R is 1).
convertNumber(1,'A').
convertNumber(2,'B').
convertNumber(3,'C').
convertNumber(4,'D').
convertNumber(5,'E').
convertNumber(6,'F').
convertNumber(7,'G').
convertNumber(8,'H').
convertNumber(9,'I').
convertNumber(1,'J').
% call createCoordinates
begin :-
L = [],
createCoordinates(L,20),
print(L).
当我在子句中打印列表时,所有元素都存在,但是当我打印出子句时,列表为空。
当我调试时,它是这样的:
可能这是一个愚蠢的错误,但我是prolog的新手,这对我来说毫无意义。
答案 0 :(得分:2)
您需要了解的有关prolog和haskell等声明性语言的一个基本方面是,它们是 - 声明性的:一旦您定义一个变量,你可以不再改变它的价值。
换句话说,编写I = 1
,然后编写I = 4
会导致程序失败。
在你的" main"你写道:
begin :-
L = [],
createCoordinates(L,20),
print(L).
在这里,您看到完全实例化 L
,这意味着从现在开始,L
始终为[]
。
因此,通常通过定义谓词来解决问题:
predicate(Some,Parameters,Prior,Post)
在<{em> 之后Post
上的某个效果Prior
上的Post
是一个值 {注意这并不意味着你只能计算Prior
createCoordinates/2
1}}:Prolog中的大多数谓词都允许你去另一个方向。)
因此,对于您的情况,您必须将createCoordinates/3
重写为createCoordinates(Lin,Q,Lout)
:
Lout
现在你需要定义这个谓词。您可以通过改变它来完成此操作:
createCoordinates(Lin,Q,Lout) :- C is Q, random(1,10,X), random(1,10,Y), convertNumber(X,Z), checkCoordinate([Z,Y],Lin,R), (C \== 0 -> (R is 0 -> createCoordinates(Lin,Q,Lout) ; (insert([X,Y],Lin,A), createCoordinates(A,Q-1,Lout)) ) ; (trace, print(Lin), print('Done!'), Lout = Lin) ).
我冒昧地重新格式化你的代码。如您所见,谓词和调用现在使用'Done!'
参数。最后,如果我们Lout = Lin
,我们设置Lout
,这意味着现在Lin
获取我们称之为谓词的trace/0
的值。
你用:
来称呼它begin :- Lin = [], createCoordinates(Lin,20,Lout), print(Lout).
消除print/1
和内部?- begin.
[[9,7],[7,1],[3,4],[7,7],[1,3],[9,1],[1,9],[8,8],[5,3],[8,3],[8,1],[6,3],[2,9],[3,6],[8,9],[6,6],[8,4],[6,3],[7,9],[4,1]]
语句会产生:
createCoordinates/3
话虽这么说,你的程序显然是用命令式思维模式编写的:这不是prolog中的程序看起来的样子。编写createCoordinates(Lin,Q,Lin) :-
Q < 0.
createCoordinates(Lin,Q,Lout) :-
Q1 is Q-1,
random(1,10,X),
random(1,10,Y),
convertNumber(X,Z),
checkCoordinate([Z,Y],Lin,1),
insert([X,Y],Lin,A),
createCoordinates(A,Q1,Lout).
的方式肯定可以改进。
更好的版本是:
Spinner
然而,即使有了这些改进,你仍然需要进行大量的重构。