Как найти оптимальный порядок обработки?

У меня есть интересный вопрос, но я точно не знаю, как его выражать...

Рассмотрим лямбда-исчисление. Для данного лямбда-выражения существует несколько возможных порядков сокращения. Но некоторые из них не прекращаются, а другие делают.

В лямбда-исчислении оказывается, что существует один конкретный порядок восстановления, который гарантированно всегда заканчивается неприводимым решением, если он действительно существует. Он называется Нормальный порядок.

Я написал простой логический решатель. Но проблема в том, что порядок, в котором он обрабатывает ограничения, по-видимому, оказывает огромное влияние на то, найдет ли он какие-либо решения или нет. В принципе, мне интересно, существует ли что-то вроде обычного порядка для моего логического языка программирования. (Или, возможно, для простой машины детерминистически решить эту проблему.)


Итак, что мне нужно. Предположительно, ответ критически зависит от того, что такое "простой логический решатель". Поэтому я попытаюсь кратко описать это.

Моя программа тесно связана с системой комбинаторов в главе 9 "Забава программирования" (Джереми Гиббонс и Оге де Мур). Язык имеет следующую структуру:

  • Ввод в решатель - это один предикат. Предикаты могут включать переменные. Выход от решателя равен нулю или более. Решение представляет собой набор переменных присваиваний, которые делают предикат истинным.

  • Переменные содержат выражения. Выражение представляет собой целое число, имя переменной или кортеж подвыражений.

  • Существует предикат равенства, который сравнивает выражения (не предикаты) для равенства. Выполняется, если подстановка каждой (связанной) переменной с ее значением делает эти два выражения одинаковыми. (В частности, каждая переменная равна себе, связана или нет). Этот предикат решается с помощью унификации.

  • Существуют также операторы для AND и OR, которые работают очевидным образом. Нет оператора NOT.

  • Существует оператор "существует", который по существу создает локальные переменные.

  • Объект для определения именованных предикатов допускает рекурсивный цикл.

Одна из "интересных вещей" о логическом программировании заключается в том, что, как только вы пишете именованный предикат, он обычно работает в фокусах и назад (а иногда и вбок). Канонический пример: предикат для объединения двух списков также может использоваться для разбиения списка на все возможные пары.

Но иногда выполнение предиката назад приводит к бесконечному поиску, если вы не измените порядок терминов. (Например, замените LHS и RHS для AND или OR). Мне интересно, существует ли какой-либо автоматизированный способ определения наилучшего порядка запуска предикатов, чтобы обеспечить быстрое завершение во всех случаях, когда набор решений конечно.

Любые предложения?