Как возможно, что он назначает бесплатную для другой бесплатной?
Использование вами слова assigning
говорит нам секрет о том, как вы думаете о Прологе.Когда вы видите =
в Прологе, это не назначение, а объединение, см .: = / 2 .Пролог работает путем объединения или, более конкретно, синтаксическое объединение .
Если Пролог может объединить две свободные переменные вместе, например A
и B
, и когда одна из них становится связанной , другая также связанав то же время, поскольку они были объединены ранее.
Хотя это и не совсем точно, другой способ думать об этом - это указатели.
Если вы начинаете с одного указателя, указывающего на 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 переменная *На 1064 * внутренне ссылаются как _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
имеют одинаковое значение, поэтому отображают их таким образом, но я не хочу тратить время на то, чтобы углубиться в код и найти детали.
Это какой-то рефлексионный материал в Прологе, о котором я не знаю?
Я бы не использовал слово Отражение для его описания.
Некоторые тестовые примеры для вашего кода.Я использовал, чтобы убедиться, что ваш код работает, если у вас есть ошибка и вы забыли спросить об этом.
:- 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.