Programming languages 反向推理引擎(查找foo(X)为真的随机X)

Programming languages 反向推理引擎(查找foo(X)为真的随机X),programming-languages,logic,libraries,inference,Programming Languages,Logic,Libraries,Inference,我知道Prolog等语言允许您编写以下内容: mortal(X) :- man(X). % All men are mortal man(socrates). % Socrates is a man ?- mortal(socrates). % Is Socrates mortal? yes 凡人(X):-人(X)。%人皆有死 人(苏格拉底)。%苏格拉底是人 -凡人(苏格拉底)。%苏格拉底是凡人吗? 对 我想要的是像这样的东西,但是向后。假设我有这个: morta

我知道Prolog等语言允许您编写以下内容:

mortal(X) :- man(X). % All men are mortal man(socrates). % Socrates is a man ?- mortal(socrates). % Is Socrates mortal? yes 凡人(X):-人(X)。%人皆有死 人(苏格拉底)。%苏格拉底是人 -凡人(苏格拉底)。%苏格拉底是凡人吗? 对 我想要的是像这样的东西,但是向后。假设我有这个:

mortal(X) :- man(X). man(socrates). man(plato). man(aristotle). 凡人(X):-人(X)。 人(苏格拉底)。 人(柏拉图)。 人(亚里士多德)。 然后我要求它给我一个随机的X,对于这个X,凡人(X)是真的(因此它应该给我一个‘苏格拉底’、‘柏拉图’或‘亚里士多德’,根据一些随机的种子)

我的问题是:

  • 这种反向推理有名字吗
  • 有支持它的语言或库吗
编辑

正如下面有人指出的那样,你可以简单地询问凡人(X),它将返回所有X,你可以从列表中随机选择一个。然而,如果这张名单非常庞大,也许有几十亿呢?显然,在这种情况下,在选择一个结果之前生成所有可能的结果是不行的


要想知道这是一个怎样的实际问题,想象一下一个简单的语法生成了一个“形容词1名词1副词及物动词形容词2名词2”形式的随机句子。如果形容词、名词、动词等的列表非常大,你可以看到组合爆炸是一个怎样的问题。如果每个列表有1000个单词,你就有1000^6个可能的句子。

我从来没有用过Prolog或类似的东西,但从提问判断

应该列出
凡人
为真的一切。之后,只需选择一个结果

为了回答你的问题

  • 我会选择“带变量的查询”
  • 据我所知,Prolog本身应该很好地支持它

我不认为您可以直接计算第n个解,但您可以计算n个第一个解(随机选取的n个),然后选取最后一个。当然,如果n=10^(大数值),这将是有问题的

你也可以这样做

mortal(ID,X) :- man(ID,X).

man(X):- random(1,4,ID), man(ID,X).
man(1,socrates).
man(2,plato).
man(3,aristotle).
但问题是,如果不是每个人都是凡人,例如,如果100万人中只有1人是凡人,那么你就必须进行大量搜索。这就像通过尝试随机数来寻找方程的解,直到找到为止。 您可以开发某种启发式方法来找到接近数字的解决方案,但这可能会影响(负面)随机性


我怀疑没有更有效的方法:你要么计算解集,然后选择一个,要么从所有解的超集中选择一个,直到找到一个解。但是不要相信我的话xd

代替Prolog的深度优先搜索,一个随机的深度优先搜索策略可以很容易地实现。所需要做的只是在选择点处对程序流进行随机化,以便每次到达分离点时,都会选择搜索树(=prolog program)上的随机极点,而不是第一个极点


尽管如此,请注意,这种方法并不能保证所有解决方案都具有同等的可能性。为了保证这一点,需要提前知道每个极点将产生多少个解来对随机化进行相应的加权。

Ah,对。但问题是,它必须是一个随机结果,而Prolog系统每次返回的结果顺序相同。虽然返回所有X并从列表中随机选择一个是很简单的,但是如果有,比如说,数十亿个可能的结果呢?
mortal(ID,X) :- man(ID,X).

man(X):- random(1,4,ID), man(ID,X).
man(1,socrates).
man(2,plato).
man(3,aristotle).