正确使用逻辑语言作为工具
Correct use of logic languages as a tool
我对 "use the right tool for the job" 编程哲学很感兴趣,我有一个问题我认为可以通过逻辑编程解决。我的意思是天真,因为我没有做过任何逻辑编程,只是着手学习。但在我仍在努力掌握概念和词汇的阶段,我希望在可能变得太深之前获得一些专家指导。
吸引我使用逻辑编程的想法是我对 "unification," 的想法的模糊了解,但我的想法是以一种我不确定是惯用的还是正确的方式使用它。给定两个对象(或树),我想通过它们的属性(或叶子)比较两者是否相等,而我想要 return 是 "difference" 的一些概念——即,给定方法这两个对象 没有 不同,为了使两者成为某种概念上的相等,必须对其中一个进行哪些更改?
例如,假设我有两个对象 chair
和 stool
。假设每个都由属性或特性列表组成,我想构建一个系统,可以 return 类似于 "chair and stool would be equal if stool's legCount
were 4
and hasBack
were true
."
的东西
出于某种原因,从语义上讲,我将其想象为一种余数,例如,chair
减去 stool
等于一 leg
。不确定这是否有帮助...
我可以想到一些愚蠢的方法来使用命令式代码来实现这一点,也可以想到一些更优雅的方法来使用函数式技术来实现它,但我有一种预感,逻辑编程可能特别适合于此。非常感谢任何关于研究方向的智慧,谢谢!
可能您想从 ILP 文献中查看 'The least general generalisation' 或 'anti unification':
以下是一些幻灯片: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] .
它给你的 Term 是我们两个对象的最不一般的泛化,以及你为取回对象所做的替换。
我对 "use the right tool for the job" 编程哲学很感兴趣,我有一个问题我认为可以通过逻辑编程解决。我的意思是天真,因为我没有做过任何逻辑编程,只是着手学习。但在我仍在努力掌握概念和词汇的阶段,我希望在可能变得太深之前获得一些专家指导。
吸引我使用逻辑编程的想法是我对 "unification," 的想法的模糊了解,但我的想法是以一种我不确定是惯用的还是正确的方式使用它。给定两个对象(或树),我想通过它们的属性(或叶子)比较两者是否相等,而我想要 return 是 "difference" 的一些概念——即,给定方法这两个对象 没有 不同,为了使两者成为某种概念上的相等,必须对其中一个进行哪些更改?
例如,假设我有两个对象 chair
和 stool
。假设每个都由属性或特性列表组成,我想构建一个系统,可以 return 类似于 "chair and stool would be equal if stool's legCount
were 4
and hasBack
were true
."
出于某种原因,从语义上讲,我将其想象为一种余数,例如,chair
减去 stool
等于一 leg
。不确定这是否有帮助...
我可以想到一些愚蠢的方法来使用命令式代码来实现这一点,也可以想到一些更优雅的方法来使用函数式技术来实现它,但我有一种预感,逻辑编程可能特别适合于此。非常感谢任何关于研究方向的智慧,谢谢!
可能您想从 ILP 文献中查看 'The least general generalisation' 或 'anti unification':
以下是一些幻灯片: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] .
它给你的 Term 是我们两个对象的最不一般的泛化,以及你为取回对象所做的替换。