传递属性在Prolog中导致无限循环

时间:2016-11-01 01:01:24

标签: prolog

假设一组类别和这些类别中的项目。某些类别是其他类别的同义词。例如,mobile_phone和cell_phone。根据规则syn(mobile_phone, cell_phone).is_a(iphone, cell_phone).,即使规则在知识库中不存在,我也需要调用is_a(iphone, mobile_phone).才能返回true。

以下是我所拥有的:

is_syn('antibiotics' , 'antineoplastics').

is_a('mitomycin', 'antibiotics').
is_a('doxorubicin liposomal', 'antineoplastics').
is_a('idarubicin', 'antineoplastics').
is_a('pentostatin', 'antibiotics').

syn(X, Y) :-
   (  is_syn(Y, X)
   ;  is_syn(X, Y)
   ).

is_a(X, Y) :-
   syn(Y, Z),
   is_a(X, Z).

1 个答案:

答案 0 :(得分:1)

这样做你想要的吗?

is_syn('antibiotics' , 'antineoplastics').

fact_is_a('mitomycin', 'antibiotics').
fact_is_a('doxorubicin liposomal', 'antineoplastics').
fact_is_a('idarubicin', 'antineoplastics').
fact_is_a('pentostatin', 'antibiotics').

syn(X,X). % So we don't lose the obvious facts.
syn(X, Y) :-
   (  is_syn(Y, X)
   ;  is_syn(X, Y)
   ).

is_a(X, Y) :-  
    syn(X,S),
    fact_is_a(S,Z),
    syn(Z,Y). % Returns all synonyms of Z

is_a(X, Y) :- % Does the transitive part of is_a
    syn(X,S),
    fact_is_a(S,Z),
    is_a(Z,Y).

我认为你遇到的问题就是这样一个堆栈:

[1] is_a(V1,Y)
[1] syn(V1, V2)
[2] is_a(V2, Y)
[2] syn(V2, V1)
[3] is_a(V1,Y)

回到我们开始的地方。

有可能实现与此相同而不会将事实称为不同的东西(这将更加优雅)。如果你确实达到了这一点,请发布它,因为我很乐意看到它。