如何用C语言编写一阶逻辑公式?

发布于 2024-09-28 14:09:28 字数 197 浏览 3 评论 0原文

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

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

这里 x 是变量,暗示是谓词,f 是函数。听起来对于所有 x,x 都意味着 x 的函数 i'e f(x)。

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

I am newbie in C and new to stackoveflow too. I have some problems in coding first oder formula like

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

Here x is a variable, implies is predicate and f is function. It sounds like for all x, x implies function of x i'e f(x).

using C. Any kind of suggestions and help will be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

じ违心 2024-10-05 14:09:28

一阶公式具有布尔命题部分(在您的示例中,“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 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)) ...
    }
 }

First order formulas have boolean propositional parts (in your example, "implies(x,f(x))") and quantifiers ("Forall x").

You should already know that coding a function call "f(x)" is coded exactly that way in C.

You code the propositional part as boolean C code using logic connectives. For your example, "implication" isn't a native C operator so you have to substitute slightly different code for it. In c, the "?" operator does the trick. "a?b:c" produces "b" if "a" is true, and "c" otherwise. For your example:

   x?f(x):false

Quantifiers mean you have to enumerate the set of possible values of the quantified variable, which always has some abstract type. In logic, this set might be infinite, but it computers it is not. In your case, you need to enumerate the set of values which could be "x"s. To do that, you need a way to represent a set; a cheesy way to do that in C is to use an array to hold the set members X, and to iterate through the array:

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 ...
}

Since a "forall" is false if any propositional instance is false, you need to exit the enumeration when you find a false example:

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" is true if any propositional instance is true, so you need to exit the enumeration when you find a true result:

// 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...

If you have multiple quantifiers, you'll end up with nested loops, one loop for each quantifier. If your formula is complex, you'll likely need several intermediate boolean variables to compute the values of the various parts.

You'll also end up with a variety of "sets" (some arrays, some linked lists, some hash tables) so you'll need to learn how to use these data structures. Also, your quantified values might not be booleans, but that's OK;
you can still pass them to functions that compute boolean values. To compute the FOL for:

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

the following code skeleton would be used (details left to the reader):

 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)) ...
    }
 }
与之呼应 2024-10-05 14:09:28

C 是一种命令式编程语言。这里的“命令”意味着执行是通过程序员明确告诉计算机要做什么来进行的。

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

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

C is an imperative programming language. "Imperative" here means that execution happens via the programmer specifically telling the computer what to do.

For what you want, Prolog is more appropriate. It is based on first-order predicate logic, and execution happens by trying to "find a resolution refutation of the negated query" that's specified by the user's goal. This approach is very unlike C since execution is much more implicit and the expression of intent looks much different.

If you have lots of time, you can write your own constraint solver or Prolog interpreter in C, but by default, C has no first-class support for what you're looking for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文