我有这个特殊的问题,我还没有解决方案。我认为如果我知道它存在相关的算法会有所帮助。
我正在寻找的算法是帮助找到满足函数返回目标的参数的算法。
例如,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#中实现该算法。
答案 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 Reasoning(Amazon,Safari Books);第3.9节介绍了统一算法。另外两个F#'ers和我去年把这本书的代码移到了F#,如果你想看看:fsharp-logic-examples。
鉴于您对问题的描述,您可以通过一些简单的约束逻辑编程(CLP)来解决它,但是AFAIK还没有人为F#实现CLP库。 miniKanren和cKanren是此类系统的两个流行的简单示例,如果您对此感兴趣,我怀疑它们需要花费很多时间移植到F#。