Prolog 为一组约束生成满足值的列表

Prolog 为一组约束生成满足值的列表,prolog,Prolog,给定一组约束,我希望高效地生成一组值 假设我的Thungus[1]有一些限制: goodThungus(X) :- X > 100, X < 1000. sin(X) = 0. 我想生成所有好的Thungi。我不知道该怎么做;我真的不知道如何有效地做这件事 注意:这当然必须是可计算的一代 [1] 为本例选择的任意对象。在完全的一般情况下,您所要求的是无法完成的:例如,假设执行f(X)=0,其中

给定一组约束,我希望高效地生成一组值

假设我的Thungus[1]有一些限制:

goodThungus(X) :-
               X > 100,
               X < 1000.
               sin(X) = 0.
我想生成所有好的Thungi。我不知道该怎么做;我真的不知道如何有效地做这件事

注意:这当然必须是可计算的一代


[1] 为本例选择的任意对象。

在完全的一般情况下,您所要求的是无法完成的:例如,假设执行f(X)=0,其中f是一个无法解析确定其根的函数。或者假设f(X)是函数“程序X停止了吗?”。没有计算机能帮你解决这个问题

您的选择基本上是:

  • 将约束集限制在可以推理的事情上。e、 不等式是好的,因为你可以识别范围,然后有效地在范围上进行交集和并集等

  • 将值集限制为足够小的数目,以便可以针对每个约束单独测试它们

更新:对于问题中所述的约束类型(可解析求解的实值范围和实值函数,且在任何范围内具有有限数量的解),我建议以下方法:

  • 编写一个生成函数,可以在给定范围内迭代返回函数的解。。。这需要进行分析,例如,利用sin(X)=0意味着X=n*pi,其中n是任意整数这一事实
  • 在范围约束上执行和绑定,以计算出需要扫描的范围(在示例中,您希望范围100
  • 将生成函数应用于每个目标范围,以创建所有可能的解决方案

    • 他正在[100..1000]中的任何X中搜索罪恶(X)=0。但这是一个纯粹的数学问题,不适用于关系逻辑推导/回溯。简单的Prolog不适合这种情况?

      我会在我的建议之前声明,我不是使用数值约束逻辑编程系统的专家,但下面是

      表面上,我认为用PROLOG解决这类问题最适合于数值约束逻辑编程系统,比如SWI-PROLOG中的REAL;不幸的是,您所要求的具体问题是寻求解决一组约束,包括非线性约束,这在PROLOG实现中似乎没有得到很好或广泛的支持;相反,它们似乎主要处理线性约束,并且通常对非线性约束的支持有限,例如
      X=sin(Y)

      以SWI-PROLOG的CLP(R)库和以下示例程序为例:

      :- use_module(library(clpr)).
      
      report_xsq_zeros :-
          findall(X, {0 = (X * X) - 10}, Results),
          write_ln(Results).
      
      report_sin_zeros :-
          findall(X, {0 = sin(X)}, Results),
          write_ln(Results).
      
      现在,执行
      report_xsq_zero
      将为我们提供:

       ?- report_xsq_zeros.
      [3.16228, -3.16228]
      true.
      
      在这里,系统正确地计算了二次
      x^2-10
      的零点,实际上大约是
      3.16228
      -3.16228
      ,其中
      x
      的范围是无界的。但是,当我们执行
      report_sin_zero
      时,我们得到:

       ?- report_sin_zeros.
      [0.0]
      true.
      
      我们看到系统只计算了函数sin(X)的一个零,即使
      X
      的范围实际上也是无界的。也许这是因为人们认识到这里有无限多的解决方案(尽管我只是猜测…)。如果我们对您要求的内容进行编程:

      report_sin_zeros :-
          findall(X, {X > 100, X < 1000, 0 = sin(X)}, Results),
          write_ln(Results).
      

      我的结论是,我要么没有演示SWI-PL CLP(R)的正确用法(我建议您自己研究一下),要么它无法解决您的特定(非线性)问题。其他CLP(R)实现的行为可能与SWI-PROLOG CLP(R)不同,但我没有安装它们,因此无法检查,但您可以尝试或其他方式;语法看起来很相似。

      让我们假设问题是可计算的。可计算的约束仍然太弱,无法使问题易于处理。例如,“是X素数吗?”虽然计算量很小,但仍然有无穷多个解,因此很难解释它是如何与其他约束相互作用的。也许您可以澄清您试图解决的问题类型?在满足某些约束的多元情况下查找数字集(整数和/或有理数),例如,当每个元素上的某个谓词为真时,范围内的所有数字集。好的,谢谢您的澄清。问题是,您需要分析谓词,以确定是否可以通过分析生成解决方案。如果没有,你可能必须扫描整个范围,这可能对整数是可行的,但对有理数是不可能的(因为在任何范围内都有无限多个…)@mikera:嗯,我有一个决定性的优势:计算机中的每一个数字表示最终都可以映射到整数。有一个高达一定精度的浮点值就足够了——它确实可以被枚举。此外,简化后,有理数的最大精度可能在1/100和1/10000之间。所以,不,我不太关心射程的产生。解决方案生成可能是一项挑战。我希望有一种更像“人工智能”的技术,而不仅仅是一种暴力的间隔。我不确定简单的序言是否是我的想法。可能复杂的序言是::-)我看了Prolog约束解算器(即SWI中的一个),但他们对单个值感兴趣(来自示例?).III有趣。我不知道sin(本身)是否真的会被使用,但是case逻辑的功能将非常强大,我预计单调性和不连续性将非常明显。我将不得不使用你们的例子,并试图对它们进行扩展。我会告诉你事情的进展。
      report_sin_zeros :-
          findall(X, {X > 100, X < 1000, 0 = sin(X)}, Results),
          write_ln(Results).
      
       ?- report_sin_zeros.
      []
      true.