Почему Prolog объединяет свободную переменную с другой свободной?

Не пробовал это с помощью комбинированных ящиков, но это работало для меня с другими элементами управления ...

ageektrapped blogpost

Он использует слой adorner здесь для отображения водяного знака.

1
задан repeat 7 March 2019 в 09:06
поделиться

1 ответ

Как возможно, что он присваивает бесплатное другому бесплатному?

Ваше использование слова 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 имеют одинаковое значение, поэтому отображает их таким образом, но я не хочу найдите время, чтобы покопаться в коде , найти детали.


Это какой-то материал для размышлений в Прологе, о котором я не знаю?

Я бы не использовал слово 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.
0
ответ дан Guy Coder 7 March 2019 в 09:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: