正确使用逻辑语言作为工具

时间:2018-05-24 17:01:55

标签: prolog logic-programming clojure-core.logic minikanren

我对"使用正确的工具感兴趣"编程哲学,我有一个问题,我认为可以用逻辑编程解决。我的意思是天真的,因为我没有完成任何逻辑编程,只是开始学习。但是,在我仍然试图掌握概念和词汇的阶段,我希望在潜在的深度之前有一些专家指导。

让我了解使用逻辑编程的想法是我对“统一”概念的模糊认识,"但我的想法是以一种我不确定是惯用还是正确的方式使用它。给定两个对象(或树),我想通过它们的属性(或叶子)比较两者的相等性,我想要返回的是一些概念"差异" - 即,给出了方法哪两个对象不同,为了使两者成为一些相等的概念,必须在其中一个中做出哪些改变?

例如,假设我有两个对象chairstool。假设每个都由一系列属性或属性组成,我想建立一个可以返回“#34”的内容的系统;如果粪便和凳子,凳子和凳子将是相等的{{1 } legCount4hasBack。"

出于某种原因,从语义上来说,我将其视为一种余数,例如true减去chair等于一stool。不确定这是否有帮助......

我可以想到一些使用命令式代码执行此操作的愚蠢方法以及使用函数技术执行此操作的一些更优雅的方法,但我有一种预感,逻辑编程可能特别适合这一点。关于哪些方向的任何智慧都将非常感谢,谢谢!

1 个答案:

答案 0 :(得分:3)

可能你想从ILP文献中研究“最不普遍的概括”或“反统一”:

以下是一些幻灯片:http://soft.vub.ac.be/~cderoove/declarative_programming/decprog7.pdf

使用逻辑第9章http://people.cs.bris.ac.uk/~flach/SL/SL.pdf中的代码:

:-op(600,xfx,'<-').

anti_unify(Term1,Term2,Term):-
    anti_unify(Term1,Term2,Term,[],S1,[],S2).

anti_unify(Term1,Term2,Term1,S1,S1,S2,S2):-
    Term1 == Term2,!.
anti_unify(Term1,Term2,V,S1,S1,S2,S2):-
    subs_lookup(S1,S2,Term1,Term2,V),!.
anti_unify(Term1,Term2,Term,S10,S1,S20,S2):-
    nonvar(Term1),nonvar(Term2),
    functor(Term1,F,N),functor(Term2,F,N),!,
    functor(Term,F,N),
    anti_unify_args(N,Term1,Term2,Term,S10,S1,S20,S2).
anti_unify(T1,T2,V,S10,[T1<-V|S10],S20,[T2<-V|S20]).



anti_unify_args(0,Term1,Term2,Term,S1,S1,S2,S2).
anti_unify_args(N,Term1,Term2,Term,S10,S1,S20,S2):-
    N>0, N1 is N-1,
    arg(N,Term1,Arg1),
    arg(N,Term2,Arg2),
    arg(N,Term,Arg),
    anti_unify(Arg1,Arg2,Arg,S10,S11,S20,S21),
    anti_unify_args(N1,Term1,Term2,Term,S11,S1,S21,S2).

subs_lookup([T1<-V|Subs1],[T2<-V|Subs2],Term1,Term2,V):-
    T1 ==Term1,
    T2 ==Term2,!.
subs_lookup([S1|Subs1],[S2|Subs2],Term1,Term2,V):-
   subs_lookup(Subs1,Subs2,Term1,Term2,V).

然后你可以查询:

?- anti_unify(object(type=chair,legs=4,hasback=true,color=red),object(type=stool,legs=3,hasback=false,color=red),T,[],S1,[],S2).
T = object(type=_1838, legs=_1808, hasback=_1778, color=red),
S1 = [chair<-_1838, 4<-_1808, true<-_1778],
S2 = [stool<-_1838, 3<-_1808, false<-_1778] .

它为您提供了这两个对象的最不一般概括的术语,以及您为了使对象返回而进行的替换。