Управление поиском в Haskell

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

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

В ленивом языке, таком как Haskell, вы не можете сделать это таким образом. Вместо этого я могу придумать два способа сделать это:

  1. Пишите код, который зависит от точного порядка вычислений, который выбран текущей версией используемого вами компилятора, с используемыми вами флагами оптимизации, чтобы все в конечном итоге происходило в правильном порядке. Вероятно, это приведет к проблемам с ремонтопригодностью.

  2. Напишите код, который пишет код, в частности, напишите код, который преобразует определение проблемы вместе с набором эвристик в последовательность инструкций на быстром языке, которая определяет точный порядок, в котором нужно что-то делать. Кажется, это имеет смысл, если вы готовы заплатить авансовые платежи.

Существуют ли другие рекомендуемые способы сделать такого рода вещи?


person rwallace    schedule 09.07.2011    source источник
comment
Возможно, вы получили бы более содержательные ответы, если бы привели конкретный пример.   -  person Dan Burton    schedule 09.07.2011
comment
Возможно, вам будет интересно взглянуть на эту реализацию A* на Haskell. Кроме того, Data.Graph. Астар   -  person Dan Burton    schedule 09.07.2011


Ответы (2)


Типичный способ сделать это на ленивом языке — определить пространство поиска как (возможно, бесконечную) структуру данных, а затем написать любую стратегию, которую вы хотите использовать для обхода этой структуры отдельно. Таким образом, вы контролируете используемую стратегию, но она отделена от определения проблемы.

person hammar    schedule 09.07.2011
comment
Хорошо, первую часть, я думаю, я понимаю, как это сделать, но как написать стратегию обхода структуры в определенном порядке? - person rwallace; 09.07.2011
comment
Например, предположим, что структура представляет собой игровое дерево. Затем вы будете проходить его рекурсивно и использовать некоторую эвристику на каждом шаге, чтобы определить, следует ли продолжать спускаться по этому поддереву или отказаться от него. - person hammar; 09.07.2011
comment
Верно, но на данном этапе продолжать опускаться не означает оценивать (в том смысле, в каком язык означает оценку)? Возвращает ли это вас к написанию кода, который зависит от точных решений, принятых языком о том, что и когда оценивается? - person rwallace; 09.07.2011
comment
В Haskell вы управляете порядком оценки через зависимости. Если результат вашей функции зависит от результата подвыражения, то подвыражение будет оцениваться всякий раз, когда необходимо оценить результат функции. Таким образом, ваш порядок оценки не будет зависеть от версии компилятора; это указано как часть языка. - person hammar; 09.07.2011
comment
Конечно, вы можете и должны полагаться на оценку не позднее, чем это необходимо. Принято ли зависеть от вычисления не раньше, чем это необходимо, то есть зависеть от точного порядка ленивых вычислений в том смысле, в каком программа на другом языке зависела бы от точного порядка строгого вычисления? - person rwallace; 09.07.2011
comment
Мои замечания о версиях компиляторов были вызваны тем, что у меня сложилось впечатление, что оптимизирующий компилятор Haskell часто использует активную оценку для экономии накладных расходов в тех случаях, когда он может доказать, что вычисления завершатся. Разве это не так? - person rwallace; 09.07.2011
comment
Я думаю, что мы могли бы говорить мимо друг друга о порядке оценки. Не определено, какие из a и b будут оцениваться первыми в a + b, но это важная часть языковой семантики, что ни один из них не оценивается, если нет запроса на результат. Компилятор должен будет доказать, что семантика не изменилась, прежде чем он произведет какую-либо активную оценку. - person hammar; 09.07.2011
comment
@rwallace: скажем, у вас есть игровое дерево, каждый узел которого является игровым состоянием с ветвями для каждого возможного хода из этого состояния. В данном узле вы можете применить эвристику, чтобы решить, стоит ли исследовать эту ветвь дальше. Если это не так, верните пустой результат. Если это так, сделайте то же самое для его дочерних узлов, затем возьмите лучший результат из них. При этом будут оцениваться только те части игрового дерева, которые эвристика считает целесообразными. - person C. A. McCann; 09.07.2011
comment
@rwallace: Все немного сложнее, если вы хотите ограничить поиск другими способами - например, поиск в ширину или использование жесткого ограничения глубины поиска, - но основная концепция та же. - person C. A. McCann; 09.07.2011

Вы можете сделать части своего кода Haskell основанными на строгой оценке

http://www.haskell.org/haskellwiki/Performance/Strictness

person Ankur    schedule 09.07.2011