如何处理在序言的目标/查询中传递的方程?

发布于 2025-01-02 01:58:27 字数 349 浏览 1 评论 0原文

我有这样的场景,其中我在 Prolog 查询中得到一个线性方程,如下所示:

?- myquery( 3X + 5Y = 10, Result).

因此,我的查询有一个方程 3X + 5Y = 10,通常采用 AX + BY = C 的形式,其中 A=3、B=5 和C=10。

现在,在我的序言程序中,我尝试定义一个谓词,该谓词可以接受上面查询中提到的表达式。也就是说,我想以某种方式获取 A、B 和 C 值以及所涉及的运算符(在上述情况下为加运算符),然后将其用于我在程序中定义的逻辑。我想知道如何做到这一点。

更通用地说,问题是如何识别通过目标/查询传递的方程中涉及的常量和运算符?

I have this scenario wherein I get a linear equation in the Prolog query like below:

?- myquery( 3X + 5Y = 10, Result).

So my query has an equation 3X + 5Y = 10, which in general assumes the form AX + BY = C, where A=3, B=5 and C=10.

Now, in my prolog program, I am trying to define a predicate that can take in the expression mentioned in the query above. That is, I somehow want to get A, B and C values and also the operator involved (in the above case the plus operator) stored and then used on the logic that I define withing the program. I am wondering how this can be done.

To be more generic, the question is how do I identify the constants and the operator involved in an equation that is passed on through the goal/query?

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

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

发布评论

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

评论(4

这个俗人 2025-01-09 01:58:27

SWI-Prolog 有一个约束 库 clp(Q,R) 在符号级别求解这些方程:

[debug]  ?- [library(clpq)].
% library(clpq) compiled into clpq 0,27 sec, 992 clauses
true.

?- {3 * X + 5 * Y = 10}.
{Y=2-3 rdiv 5*X}.

Eclipse 肯定会有更多东西 先进的。这些库并不简单、困难...

您感兴趣的是,使用 Prolog 语法作为宿主语言,因此可以应用常用的内置函数来识别变量、常量等。

SWI-Prolog has a constraint library clp(Q,R) that solve at symbolic level these equations:

[debug]  ?- [library(clpq)].
% library(clpq) compiled into clpq 0,27 sec, 992 clauses
true.

?- {3 * X + 5 * Y = 10}.
{Y=2-3 rdiv 5*X}.

Eclipse will surely have something more advanced. These libraries aren't simple, tough...

Of interest to you, the Prolog syntax is used, as a host language, so the usual builtins could be applied for identify vars, constants, and the like.

紅太極 2025-01-09 01:58:27

以下文字记录可能具有启发性:

32 ?- Term = (3*_X + 5*_Y = 10), functor(Term,F,A).

Term = 3*_G527+5*_G530=10
F = =
A = 2 

33 ?- Term = (3*_X + 5*_Y = 10), arg(Arg,Term,Val).

Term = 3*_G459+5*_G462=10
Arg = 1
Val = 3*_G459+5*_G462 ; % user pressed ';' interactively

Term = 3*_G459+5*_G462=10
Arg = 2
Val = 10 ; % user pressed ';' interactively

No
35 ?- Term = (3*_X + 5*_Y = 10), arg(1,Term,Val1), functor(Val1,F1,A1),
      arg(2,Val1,Val12).

Term = 3*_G693+5*_G696=10
Val1 = 3*_G693+5*_G696
F1 = +
A1 = 2
Val12 = 5*_G696 

最后一个查询如下:对于给定的 TermTerm 的第一个 argVal1 >,Val1 的函子是 F1,元数为 A1(意思是,它有 A1 args - 子部分 - 本身),以及第二个Val1 中的术语的 arg 存储在 Val12 名称下。澄清一下,Prolog 中的任何符号数据都采用 fff(aa,bb,cc,...) 的形式,其中 fff 是某个名称,称为函子 (functor) ,并且可以通过 arg 调用访问该表达式中的“参数”。

这意味着原始表达式 (3*_X + 5*_Y = 10) 实际上在 Prolog 中存储为 '='( '+'( '*'(3,_X), '*'(5,_Y)), 10)。当您到达原子部分(元数为 0 的函子)时,您可以进一步检查它们:

47 ?- arg(1,(3*X),V), functor(V,F,A), number(V).

X = _G441
V = 3
F = 3
A = 0 

Yes

编辑:回答您的其他问题(来自评论):

1 ?- (3*_X + 5*_Y = 10) = (A*X + B*Y = C).

A = 3
X = _G412
B = 5
Y = _G415
C = 10 

Yes

如果您坚持不写出乘法符号* 明确地,您必须将术语表示为字符串,并分析该字符串。这将是一项更加复杂的任务。

编辑:要尝试的另一件事是 =.. 谓词,称为“Univ”:

4 ?- (3*_X + 5*_Y = 10) =.. X.

X = [=, 3*_G454+5*_G457, 10] 

Yes
5 ?- (3*_X + 5*_Y = 10) =.. X, X=[X1,X2,X3], X2 =.. Y.

X = [=, 3*_G545+5*_G548, 10]
X1 = =
X2 = 3*_G545+5*_G548
X3 = 10
Y = [+, 3*_G545, 5*_G548] 

Yes

The following transcript may prove illuminating:

32 ?- Term = (3*_X + 5*_Y = 10), functor(Term,F,A).

Term = 3*_G527+5*_G530=10
F = =
A = 2 

33 ?- Term = (3*_X + 5*_Y = 10), arg(Arg,Term,Val).

Term = 3*_G459+5*_G462=10
Arg = 1
Val = 3*_G459+5*_G462 ; % user pressed ';' interactively

Term = 3*_G459+5*_G462=10
Arg = 2
Val = 10 ; % user pressed ';' interactively

No
35 ?- Term = (3*_X + 5*_Y = 10), arg(1,Term,Val1), functor(Val1,F1,A1),
      arg(2,Val1,Val12).

Term = 3*_G693+5*_G696=10
Val1 = 3*_G693+5*_G696
F1 = +
A1 = 2
Val12 = 5*_G696 

The last query reads: for Term as given, 1st arg of Term is Val1, the functor of Val1 is F1 with arity A1 (meaning, it has A1 args - subparts - itself), and 2nd arg of the term in Val1 is stored under Val12 name. To clarify, any symbolic data in Prolog is in the form of fff(aa,bb,cc,...) where fff is some name, called functor, and the "arguments" in that expression can be accessed through the arg call.

That means that the original expression (3*_X + 5*_Y = 10) is actually stored in Prolog as '='( '+'( '*'(3,_X), '*'(5,_Y)), 10). When you get to the atomic parts (functors with arity 0), you can check them further:

47 ?- arg(1,(3*X),V), functor(V,F,A), number(V).

X = _G441
V = 3
F = 3
A = 0 

Yes

EDIT: to answer your other question (from the comments):

1 ?- (3*_X + 5*_Y = 10) = (A*X + B*Y = C).

A = 3
X = _G412
B = 5
Y = _G415
C = 10 

Yes

If you insist on not writing out the multiplication sign * explicitly, you will have to represent your terms as strings, and to analyze that string. That would be a much more involved task.

EDIT: another thing to try is =.. predicate, called "Univ":

4 ?- (3*_X + 5*_Y = 10) =.. X.

X = [=, 3*_G454+5*_G457, 10] 

Yes
5 ?- (3*_X + 5*_Y = 10) =.. X, X=[X1,X2,X3], X2 =.. Y.

X = [=, 3*_G545+5*_G548, 10]
X1 = =
X2 = 3*_G545+5*_G548
X3 = 10
Y = [+, 3*_G545, 5*_G548] 

Yes
久伴你 2025-01-09 01:58:27

例如,您可以使用术语检查谓词:arg/3、functor/3、var/1、(=..)/2 等。

You can for example use term inspection predicates: arg/3, functor/3, var/1, (=..)/2 etc.

秋千易 2025-01-09 01:58:27

您可能想看一下使用术语重写规则实现的符号微分的示例;他们处理这样的表达。

这是《Clause and Effect》一书中的一章(减去 1 页),您可能会觉得有用:
<一href="http://books.google.com/books?id=fbYjjEn6a_4C&lpg=PA69&ots=sphfpOafZc&dq=prolog%20term-rewrite%20symbolic- Differentiation&pg=PA69#v=onepage&q=prolog %20term-rewrite%20symbolic- Differentiation&f=false" rel="nofollow noreferrer">子句和效果 - 第六章:术语重写

另一篇来自《Prolog 的艺术:高级编程技术》
<一href="http://books.google.com/books?id=w-XjuvpOrjMC&lpg=PA439&ots=4Xz3XNF0Mw&dq=programming%20in%20prolog%20s ymbolic%20微分&pg=PA439#v=onepage&q=编程%20in%20prolog%20symbolic%20微分&f=false" rel="nofollow noreferrer">23 方程求解器

在 Prolog 中编程 还有一个关于符号微分的部分 (7.11)。

You might want to take a look at examples of symbolic differentiation implemented using term rewrite rules; they handle such expressions.

Here's a chapter (minus 1 page) from the book Clause and Effect that you might find useful:
Clause and Effect - Chapter Six: Term Rewriting

Another from The art of Prolog: advanced programming techniques
23 An equation solver

Programming in Prolog also has a section (7.11) on symbolic differentiation.

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