Как возможно, что он присваивает бесплатное другому бесплатному?
blockquote>Ваше использование слова
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 переменнаяB
внутренне упоминается как_480
Обратите внимание, что теперь
A
иB
внутренне ссылаются на одно и то же:_480
.Далее выполняется код
A = 5
В строке 5 переменная
A
внутренне ссылается на_480
, которая теперь связана со значением5
.
В строке 6 переменнаяB
внутренне ссылается на_480
, которая теперь связана со значением5
.Когда это произошло, было не две отдельные привязки, а одна привязка к одному местоположению, которое из-за объединения и, следовательно, ссылки на одно и то же местоположение, две переменные стали привязаны к значению с одним действием. [ 1179]
Итак, когда вы видите
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
имеют одинаковое значение, поэтому отображает их таким образом, но я не хочу найдите время, чтобы покопаться в коде , найти детали.Это какой-то материал для размышлений в Прологе, о котором я не знаю?
blockquote>Я бы не использовал слово 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.
Переносимые правила make могут использовать только разные суффиксы, префиксы должны быть одинаковыми.
.c.o:
$(COMPILE) -DCHECKING -c -o $@ $<
Суффикс не обязательно начинается с точки, однако. (В этом случае вы должны сообщить Automake, какие у вас суффиксы, потому что он не может угадать.) Так, например, у вас может быть что-то вроде следующего, если вы переименуете check_showdns.o
в showdns_check.o
]:
SUFFIXES = _check.o
check_libapdns_LDADD = @CHECK_LIBS@ showdns_check.o
.c_check.o:
$(COMPILE) -DCHECKING -c -o $@ $<
I'd rather try to disable the warning or just ignore it. GNU make exists for all relevant Unix-like platforms; there is no practical reason to spend time maintaining makefile portability. GNU make is also feature-wise superior to most other make dialects.