寻找算法寻求参数以满足给定函数的回报

时间:2013-10-09 15:24:47

标签: algorithm f# functional-programming prolog unification

我有这个特殊的问题,我还没有解决方案。我认为如果我知道它存在相关的算法会有所帮助。

我正在寻找的算法是帮助找到满足函数返回目标的参数的算法。

例如,a works for b表示为(a,b)

Given: [ (a,b); (b,c) ]

函数works将确保它们与布尔值的关系

let works a b -> true
let works b c -> true

现在我得到了

[ (a, "x"); ("x", c) ]

如果我想要这两个绑定是真的,那么这个函数必须是真的

let works a "x" -> true
let works "x" c -> true

现在我正在尝试编写一个函数/算法来帮助我实现这样的"x" = b

我在想回溯,但还不知道如何实现它。如果有人能给我提示,我将不胜感激。

作为旁注,我正在使用函数式编程范例在F#中实现该算法。

2 个答案:

答案 0 :(得分:4)

你是正确的,你需要backward chaining而杰克是正确的,你需要统一,但具体而言,你需要通过反向链接进行句法统一。

您的问题不是新问题,但在CS:StackExchange How to implement a prolog interpreter in a purely functional language?上作为Prolog/Recursive Rules进行了更全面的回答

虽然这会让你走上正确的道路,但根据你想要解决的问题,你可能会发现这可能不像看起来那么容易。

修改

我在一些有效的F#代码上测试了你的例子,它确实有效,但我无法向公众发布代码,抱歉。

对于您给出的示例,只需统一即可完成,无需反向链接。

您需要为

创建事实
works(a,b).
works(b,c).

和查询

works(a,X),works(X,c).

答案是

X = b

如果你想在中间对多个人进行扩展,那么你需要使用反向链接,因为你必须创建一个递归的从属规则。

您需要为

创建事实
works(a,b).
works(b,c).
works(c,d).

和规则

subordinate(X,Z) :- works(X,Z).
subordinate(X,Z) :- works(X,Y), subordinate(Y,Z).

和查询

subordinate(a,X),subordinate(X,d).

答案是

X = b,c

您必须创建类型,统一和反向链接算法。您可以选择在REPL上创建解析器和漂亮的打印机和图层,但不需要它。

事实,规则和查询以人的方式显示,但如果您跳过解析器和漂亮的打印机,则必须将它们编码为AST。即

("works", [Const "a", Const "b"]) 

大写字母代表Prolog变量。即X Y Z
小写字母代表Prolog常量。即a b c

您的工作问题只是经典祖先示例的变体。请参阅:{{3}}

答案 1 :(得分:3)

您所描述的算法是Unification - 它是Prolog的基础,在F#中实现并不是非常困难。

我建议您阅读约翰哈里森的Handbook of Practical Logic and Automated ReasoningAmazonSafari Books);第3.9节介绍了统一算法。另外两个F#'ers和我去年把这本书的代码移到了F#,如果你想看看:fsharp-logic-examples

鉴于您对问题的描述,您可以通过一些简单的约束逻辑编程(CLP)来解决它,但是AFAIK还没有人为F#实现CLP库。 miniKanrencKanren是此类系统的两个流行的简单示例,如果您对此感兴趣,我怀疑它们需要花费很多时间移植到F#。