【问题标题】:How to code first order logic formula in C?如何在 C 中编写一阶逻辑公式?
【发布时间】:2010-10-23 07:18:14
【问题描述】:

我是 C 的新手,也是 stackoveflow 的新手。我在编码一阶公式时遇到了一些问题,例如

forall([X],implies(X,f(X)))

这里x是一个变量,implicit是谓词,f是函数。听起来对于所有 x,x 都意味着 x 即 f(x) 的函数。

使用 C。任何形式的建议和帮助将不胜感激。

【问题讨论】:

  • 你想用这个公式做什么?另外,X 和 f(X) 是布尔值吗?如果不是,implies 对非布尔参数表示什么?
  • X 和 f(x) 是参数。暗示在 x 和 f(x) 之间建立了某种关系。 Implies 是一个带有两个参数的符号。我会尽量让你更清楚,因为 x 是一个变量,它可以保存任何值。对于某个瞬间 x 有 a,b,c 。其中 a,b,c 是常数。由于该公式适用于 x 的所有成员,因此该公式将类似于暗示(a,f(a)),暗示(b,f(b))等等......我的程序的主要问题是,我需要将不同的常量值传递给变量,并生成用常量替换变量的公式。

标签: c logic


【解决方案1】:

一阶公式具有布尔命题部分(在您的示例中为“implies(x,f(x))”)和量词(“Forall x”)。

您应该已经知道在 C 中编写函数调用“f(x)”的编码方式正是如此。

您使用逻辑连接将命题部分编码为布尔 C 代码。对于您的示例,“暗示”不是本机 C 运算符,因此您必须为它替换稍有不同的代码。在 c 中,“?”运营商做到了。如果“a”为真,“a?b:c”产生“b”,否则产生“c”。以您为例:

   x?f(x):false

量词意味着你必须枚举量化变量的一组可能值,它总是有一些抽象类型。在逻辑上,这个集合可能是无限的,但它不是。在您的情况下,您需要枚举可能是“x”的值集。为此,您需要一种表示集合的方法;在 C 中实现这一点的一种俗气的方法是使用数组来保存集合成员 X,并遍历数组:

type_of_x set_of_x[1000];
  ... fill x somehow ...
for(i=1;i<number_of_set_elements;i++)
{   x= set_of_x[i];
      ... evaluate formula ...
}

由于如果任何命题实例为假,则“forall”为假,因此您需要在找到错误示例时退出枚举:

boolean set_of_x[1000]; // in your example, x must be a boolean variable
// forall x
... fill x somehow ...
final_value=true;
for (i=1;i<number_set_elements; i++)
{  x= set_of_x[i];
   if (x?f(x):false)
      { final_value=false;
         break;
      }
}
... final_value set correctly here...

如果任何命题实例为真,则“exists”为真,因此当找到真结果时需要退出枚举:

// exists x
... fill x somehow ...
final_value=false;
for (i=1;i<number_set_elements; i++)
{  x= set_of_x[i];
   if (x?f(x):false)
      { final_value=true;
         break;
      }
}
... final_value set correctly here...

如果您有多个量词,最终会出现嵌套循环,每个量词一个循环。如果您的公式很复杂,您可能需要几个中间布尔变量来计算各个部分的值。

您最终还会得到各种“集合”(一些数组、一些链表、一些哈希表),因此您需要学习如何使用这些数据结构。此外,您的量化值可能不是布尔值,但没关系; 您仍然可以将它们传递给计算布尔值的函数。计算 FOL:

 forall p:Person old(p) and forall f:Food ~likes(p,f)

将使用以下代码框架(细节留给读者):

 person array_of_persons[...];
 foods array_of_foods[...]

 for (i=...
 { p=array_of_persons[i];
   is_old = old(p);
   for(j=...
    { f=array_of_foods[j];
      ...
         if (is_old && !likes(p,f)) ...
    }
 }

【讨论】:

    【解决方案2】:

    C 是一种命令式编程语言。这里的“命令式”意味着执行是通过程序员专门告诉计算机要做什么而发生的。

    对于你想要的,Prolog 更合适。它基于一阶谓词逻辑,并通过尝试“找到否定查询的解析反驳”来执行,这是用户目标指定的。这种方法与 C 非常不同,因为执行更加隐含并且意图的表达看起来大不相同。

    如果你有很多时间,你可以用 C 编写你自己的约束求解器或 Prolog 解释器,但默认情况下,C 对你正在寻找的东西没有一流的支持。

    【讨论】:

    • 用直接接受它们的语言编写一阶逻辑方程更容易,用 Prolog 编写它们不太容易,用 C 编写它们也不太容易。但是反对对它们进行编码C 中的任何计算在程序上都是不方便的,并且很多代码都是用 C 编写的。OP 问如何,而不是它是否漂亮。
    猜你喜欢
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 2019-07-04
    相关资源
    最近更新 更多