2010-04-26 42 views
3

这可能是一个非常愚蠢的问题(我刚刚在几个小时前开始学习Prolog),但可以找到与原子有关的所有子句吗?例如,假设下面的知识库:查找与原子有关的所有子句

cat(tom). 
animal(X) :- cat(X). 

,是有办法,以获取有关汤姆每一个可能的信息(或至少所有在基本明确陈述的事实)?据我所知,这样的查询是不可能的:

?- Pred(tom). 

,所以我想我能写会推断出正确信息的规则:

meta(Object, Predicate) :- 
    Goal =.. [Predicate, Object], 
    call(Goal). 

,这样我可以写的查询,如

?- meta(tom, Predicate). 

但这不起作用,因为call的参数未被充分实例化。所以基本上我的问题是:这是否可能,或者是否Prolog不设计提供这种信息?如果不可能,为什么?

回答

1

您可以使用ISO谓词“current_predicate/1”来找出可以调用的内容。 下面是一个简单的程序:

 
cat(tom). 
animal(X) :- cat(X). 

info(Arg,Info) :- current_predicate(PredName/1), 
    Info =.. [PredName,Arg], call(Info). 
all_info(Arg,L) :- findall(I,info(Arg,I),L). 

您可以使用该程序如下(我使用SICStus Prolog的BTW):

 
| ?- info(tom,X). 
X = animal(tom) ? ; 
X = cat(tom) ? ; 
no 
| ?- all_info(tom,X). 
X = [animal(tom),cat(tom)] ? 
yes 

一般情况下,你可以使用

current_predicate
如下:

 
| ?- current_predicate(X). 
X = info/2 ? ; 
X = animal/1 ? ; 
X = cat/1 ? ; 
X = all_info/2 ? ; 
no 
+0

这很有趣!然而,我发现必须根据知识库中所有可能的谓词测试参数感到很伤心,我认为如果功能嵌入语言中,可能会有更高效的方法实现此目的。我提出的解决方案的另一个问题是我的Prolog引擎(SWI-Prolog)在current_predicate/1的结果集中包含所有预定义的谓词(如atomic/1,functor/3等),最终导致到上下文错误;你有什么可以阻止的建议吗?尽管如此,非常感谢您的深刻解答! – 2010-04-28 15:02:16

+0

关于我以前的评论,我刚刚发现了predicate_property/2,这可能有助于我解决我所描述的问题。 – 2010-04-28 15:18:50