maxmin([X|L], Max, Min) :-
maxmin(L, X, X, Max, Min),
!.
maxmin([], CurrentMax, CurrentMin, Max, Min) :-
Max is CurrentMax,
Min is CurrentMin,
!.
maxmin([X|L], CurrentMax, CurrentMin, Max, Min) :-
CurrentMax2 is max(X, CurrentMax),
CurrentMin2 is min(X, CurrentMin),
maxmin(L, CurrentMax2, CurrentMin2, Max, Min).
执行查询?- maxmin([2],Max,Min).
后,它将返回Max = Min, Min = 2.
。
为什么?我有几个变体,似乎没有一个工作。如何将免费分配给另一个免费的?这是Prolog的一些反思,我不知道吗?
跟踪也没有表现出任何特别有趣的东西。也就是说,它从Exit: (8) maxmin([2], 2, 2) ? creep
退出,对我来说看起来非常好。只有当我有一个列表1时才会发生这种情况。
我显然不理解Prolog,但我无法弄清楚我错在哪里。有什么指针吗?
如何将免费分配给另一个免费的?
你使用assigning
这个词告诉我们你如何看待Prolog的秘密。当你在Prolog中看到=
时,这不是任务,而是统一,请参阅:=/2。 Prolog通过统一或更具体地syntactic unification工作。
如果Prolog可以统一两个free variables,例如A
和B
,当其中一个变成bound时,另一个也同时被绑定,因为它们之前是统一的。
虽然不完全准确,但另一种思考方式就是指针。
如果你从一个指向A
的指针开始,另一个指针指向B
,它们是不同的位置,后者发现A
和B
是统一的,那么指向A
和B
的指针将被调整为现在指向相同的位置。然而,他们指向的位置仍然是一个未绑定的位置,因为A
或B
都没有值。当A
或B
绑定到某个值时,它们都会同时绑定,因为指针指向同一位置。
这是一些测试代码,用于演示详细信息。
test_01 :-
format('A: ~w~n',[A]),
format('B: ~w~n',[B]),
A = B,
format('A: ~w~n',[A]),
format('B: ~w~n',[B]),
A = 5,
format('A: ~w~n',[A]),
format('B: ~w~n',[B]).
运行此命令将返回以下内容事后我手工补充了评论。
?- test_01.
A: _480 % Line 1
B: _486 % Line 2
A: _480 % line 3
B: _480 % line 4
A: 5 % Line 5
B: 5 % Line 6
true.
在第1行中,变量A
在内部被引用为未绑定变量:_480
在第2行中,变量B
在内部被引用为未绑定变量:_486
请注意,_480
和_486
代表两个不同的未绑定变量。
请注意,A
和B
在内部并未引用相同的内容。
接下来,代码执行A = B
然后
在第3行中,变量A
在内部被称为_480
在第4行中,变量B
在内部被称为_480
请注意,现在A
和B
在内部引用相同的内容:_480
。
接下来,代码执行A = 5
在第5行中,变量A
在内部引用了_480
,它现在与值5
绑定。
在第6行中,变量B
在内部引用了_480
,它现在与值5
绑定。
当发生这种情况时,没有两个单独的绑定,但是一个绑定到一个位置,由于统一,因此对同一位置的引用,两个变量被绑定到一个操作的值。
因此,当你看到B = A, A = 2.
时,它可以意味着B
和A
统一,(引用相同的位置),并且B
位置的界限值是2
,这也是B
和A
的B
的相同值。统一。
然而,在您的具体示例中,由于Max
和Min
从未统一,因此它只是SWI-Prolog显示它们的特定方式。
我跑了一些你的例子,看看你究竟注意到了什么。
?- leash(-all),visible(+all),trace.
true.
[trace] ?- maxmin([2],Max,Min).
Call: (8) maxmin([2], _4408, _4410)
Unify: (8) maxmin([2], _4408, _4410)
Call: (9) maxmin([], 2, 2, _4408, _4410)
Unify: (9) maxmin([], 2, 2, _4408, _4410)
Call: (10) _4408 is 2
Exit: (10) 2 is 2
Call: (10) _4410 is 2
Exit: (10) 2 is 2
Exit: (9) maxmin([], 2, 2, 2, 2)
Exit: (8) maxmin([2], 2, 2)
Max = Min, Min = 2.
可能是SWI-Prolog保留了一个显示值表,并且它注意到Max
和Min
都具有相同的值,因此以这种方式显示它们,但我不想花时间挖掘code找到细节。
这是Prolog的一些反思,我不知道吗?
我不会用Reflection这个词来形容它。
一些代码测试用例。我曾经确保你的代码工作以防万一你有一个错误并忘了询问它。
:- begin_tests(maxmin_tests).
maxmin_test_case([1],1,1).
maxmin_test_case([1,2],2,1).
maxmin_test_case([2,1],2,1).
maxmin_test_case([1,2,3],3,1).
maxmin_test_case([3,2,1],3,1).
maxmin_test_case([2,3,1],3,1).
maxmin_test_case([3,1,2],3,1).
test(1,[forall(maxmin_test_case(Input,Expected_max,Expected_min))]) :-
maxmin(Input,Max,Min),
assertion( Max == Expected_max ),
assertion( Min == Expected_min ).
test(2,[fail]) :-
maxmin([],_,_).
:- end_tests(maxmin_tests).
示例运行
?- run_tests.
% PL-Unit: maxmin_tests ........ done
% All 8 tests passed
true.