比如我有:从知识库中获取随机谓词。序言
upred(mary, have, knife).
upred(john, have, sword).
upred(sam, have, bowl).
upred(sword, is, long).
我怎样才能获得随机谓语?
% call this and get random predicate as Pred
get_random_pred(Pred) :-
比如我有:从知识库中获取随机谓词。序言
upred(mary, have, knife).
upred(john, have, sword).
upred(sam, have, bowl).
upred(sword, is, long).
我怎样才能获得随机谓语?
% call this and get random predicate as Pred
get_random_pred(Pred) :-
有趣的是,这也是我最近一直担心的事情。我有一个部分解决方案,它依赖于动态存储并识别您希望随机获得的事实。我并不喜欢它,因为它取决于动态存储,也取决于元数据的制作,而元数据可以不受限制。但是,您的目的可能已足够。它也不能完全捕捉你的API,因为你必须提供一些线索,说明你感兴趣的事实。实际上,它可能会工作得很好,因为你不可能发现自己处于其中任何事实将会这样做,因为它可能会在下一次模式匹配时失败。
我的基本技巧是使用=..
反汇编谓词,并使用asserta
为每个事实分配一个索引值。如果你想让这个表现更好,你必须使用一些索引指令来告诉Prolog你希望它索引到我的random_fact
的第三个字段,但是我没有那么做。对于小型数据库(不是WordNet),这可能是好的,但对于较大的数据库,您可能需要性能。
% random_fact(Head, Instantiation, Index)
:- dynamic(random_fact/3).
% fact_count(Head, Count)
:- dynamic(fact_count/2).
% one big side-effect to make it possible to query for a random predicate
prepare_randomization_metadata(Goal) :-
findall(Goal, Goal, Occurrances),
prepare_randomization_metadata(Occurrances, 0),
Goal =.. [Head|_],
length(Occurrances, N),
asserta(fact_count(Head, N)).
prepare_randomization_metadata([], _).
prepare_randomization_metadata([Goal|Goals], N) :-
Goal =.. [Head|_],
asserta(random_fact(Head, Goal, N)),
N1 is N+1,
prepare_randomization_metadata(Goals, N1), !.
所以,你可以看到,这里的引擎基本上是一个给定的目标,并建立一个小的元数据库。这可能可以通过一个比我更了解Prolog的人来改善。要使用它,你驾驶它就像这样:
?- prepare_randomization_metadata(upred(X, Y, Z)).
true.
现在,你必须在它的事实像这样的数据库:
random_fact(upred, upred(mary, have, knife), 0).
random_fact(upred, upred(john, have, sword), 1).
...
这是你可以用Prolog的理智战胜了。所以如果你想第二个谓语,可以查询它像这样:
?- random_fact(upred, X, 1)
X = upred(mary, have, knife) ;
false.
现在get_random_pred
是很容易的,但我们需要一个额外的参数来识别“厚道”其实我们想:
get_random_pred(Head, Pred) :-
fact_count(Head, N),
% pick a random number between 0 and the # of facts we have for this pred
random(0, N, I),
random_fact(Head, Pred, I), !.
我还不够好,但是Prolog告诉你为什么这有时候认为它有多种解决方案,但它确实有,所以我在最后插入了红色的裁剪。但是,如果你需要多种解决方案,编写一个能够完成这个任务的版本也很容易。
endless_random_facts(Head, Fact) :- repeat, get_random_pred(Head, Fact).
例如:
?- get_random_pred(upred, X).
X = upred(sword, is, long) ;
X = upred(john, have, sword) ;
X = upred(mary, have, knife) ;
X = upred(john, have, sword) ;
X = upred(john, have, sword) ;
无论如何,我希望这会有所帮助,尽管不足。我只在SWI-Prolog中测试过。
随机在...?!你能给Pred一个样本结果吗?谓词的参数应从哪组值中取出? – ThomasH