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,但是我无法弄清楚我的生活中哪里错了。有指针吗?
答案 0 :(得分:3)
它有可能将一个空闲空间分配给另一个空闲空间吗?
您对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
是统一的(引用相同的位置),并且{{1 }}是B
,由于2
和B
是统一的,因此它也是A
的绑定值。
但是在您的特定示例中,由于B
和Max
从未统一,所以这只是SWI-Prolog显示它们的特殊方式。
我跟踪了您的示例,以准确了解您的注释。
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.
和Max
都具有相同的值,所以以这种方式显示它们,但我不想花时间深入code来查找详细信息。
这是我不知道的Prolog中的一些反思吗?
我不会使用单词Reflection来描述它。
您的代码的一些测试用例。我曾经确保您的代码可以正常运行,以防万一您有一个错误而忘了询问它。
Min
示例运行
:- 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).