Обнаружение некоторых циклов в целях Пролога, которые не заканчиваются универсально
TL;DR: этот вопрос об одном конкретном аспекте оценки кандидатов-сбоев-срезов.
Следующий код ancestor_of/2
выражает транзитивное замыкание child_of/2
:
ancestor_of (X, Y): - child_of (Y, X). ancestor_of (X, Z): - child_of (Z, Y), ancestor_of (X, Y).
Если мы определим child_of/2
и включить несколько циклов...
child_of (xx, xy). child_of (xy, xx). child_of (x, x).
... ancestor_of(X, Y)
не заканчивается универсально:
? - ancestor_of (X, Y), ложь. ** ПЕТЛИ **
С помощью SWI-Prolog мы можем ограничить объем работы, вложенной в выполнение запроса:
? - время ( call_with_inference_limit ((ancestor_of (_, _), false), 10000, R)). % 10,008 выводов, 0,002 ЦП за 0,002 секунды (100% ЦП, 4579243 Lips) R = inference_limit_exceeded; % 5 выводов, 0,000 CPU за 0,000 секунд (85% CPU, 235172 Lips) ложный.
Хорошо, но это может быть лучше!
- Во-первых, мы могли бы точно доказать, что цель зациклена.
- Во-вторых, мы могли бы сделать это с меньшими усилиями.
Давайте добавим дополнительный аргумент ancestor_of/2
для передачи информации о стеке вызовов!
ancestor_of_open (X, Y, Открыть):- G = ancestor_of(X,Y), (участник (G, Open) -> бросить (петля (G,Open)); ancestor_of_aux(X, Y, [G| Открыть])). ancestor_of_aux (X, Y, _Open): - child_of (Y, X). ancestor_of_aux (X, Z, Open): - child_of (Z, Y), ancestor_of_open (X, Y, Открыть).
Пример запроса:
? - время (ancestor_of_open (X, Y, [])). % 4, 0,000 CPU за 0,000 секунд (92% CPU, 219696 Lips) X = xy, Y = хх; Выводы% 1, 0,000 CPU за 0,000 секунд (79% CPU, 61839 Lips) Х = хх, Y = xy; Выводы% 1, 0,000 CPU за 0,000 секунд (79% CPU, 61084 Lips) X = Y, Y = x; % 8 выводов, 0,000 CPU за 0,000 секунд (87% CPU, 317473 Lips) Х = Y, Y = хх; % 11 выводов, 0,000 CPU за 0,000 секунд (90% CPU, 262530 Lips) ОШИБКА: необработанное исключение: цикл (ancestor_of(_G282,xx),[ancestor_of(_G282,xy),ancestor_of(_G282,xx)])
Это оно?! Это было слишком просто. Это охватывает общий случай?
Я чувствую, что упускаю что-то важное, но не могу указать пальцем на это. Пожалуйста помоги!