【问题标题】:A reverse inference engine (find a random X for which foo(X) is true)反向推理引擎(找到 foo(X) 为真的随机 X)
【发布时间】:2011-11-16 01:09:35
【问题描述】:

我知道像 Prolog 这样的语言允许您编写如下内容:

凡人(X):- 人(X)。 % 所有的人都会死
人(苏格拉底)。 % 苏格拉底是个男人

?- 凡人(苏格拉底)。 % 苏格拉底会死吗?
是的

我想要的是这样的东西,但是倒过来了。假设我有这个:

凡人(X):- 人(X)。
人(苏格拉底)。
人(柏拉图)。
人(亚里士多德)。

然后我要求它给我一个随机 X,其中 mortal(X) 为真(因此根据一些随机种子,它应该给我“苏格拉底”、“柏拉图”或“亚里士多德”之一)。

我的问题是:

  • 这种反向推理有名字吗?
  • 是否有任何语言或库支持它?

编辑

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

要了解这将如何成为一个实际问题,请想象一个简单的语法,它生成了一个形式为“形容词1 名词1 副词传递_动词形容词2 名词2”的随机句子。如果形容词、名词、动词等的列表非常大,你可以看到组合爆炸是一个问题。如果每个列表有 1000 个单词,那么您将有 1000^6 个可能的句子。

【问题讨论】:

    标签: programming-languages logic libraries inference


    【解决方案1】:

    可以轻松实现随机的深度优先搜索策略,而不是 Prolog 的深度优先搜索。所需要做的就是在选择点随机化程序流,以便每次达到析取时都会选择搜索树上的一个随机极点(= prolog 程序)而不是第一个。

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

    【讨论】:

      【解决方案2】:

      我从未使用过 Prolog 或类似的东西,但从 what Wikipedia says on the subject 来看,询问

      ?- mortal(X).
      

      应该列出所有mortal 为真的东西。之后,只需选择其中一个结果即可。

      所以回答你的问题,

      • 我会选择“其中包含变量的查询”
      • 据我所知,Prolog 本身应该可以很好地支持它。

      【讨论】:

      • 啊,对。但是,问题在于它必须是随机结果,而 Prolog 系统每次都会以相同的顺序返回结果。虽然返回所有 X 并从列表中随机选择一个很简单,但如果有数十亿个可能的结果怎么办?
      【解决方案3】:

      我不认为您可以直接计算第 n 个解决方案,但您可以计算第 n 个第一个解决方案(n 个随机选择)并选择最后一个。当然,如果 n=10^(big_number)...

      你也可以这样做

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

      但问题是,如果不是每个人都是凡人,例如,如果 1000000 人中只有 1 人是凡人,那么您将不得不进行大量搜索。这就像通过尝试随机数直到找到一个来寻找方程的解。 您可以开发某种启发式方法来找到接近数字的解决方案,但这可能会(负面地)影响随机性。

      我怀疑没有办法更有效地做到这一点:您要么必须计算一组解决方案并选择一个,要么选择所有解决方案的超集中的一个成员,直到找到一个解决方案。但是不要相信我的话xd

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-07
        • 2012-08-27
        • 1970-01-01
        • 1970-01-01
        • 2016-06-11
        • 2011-03-30
        • 1970-01-01
        相关资源
        最近更新 更多