1

私はこのシナリオを持っており、以下のようなPrologクエリで線形方程式を取得します。

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

したがって、私のクエリには3X + 5Y = 10の方程式があり、これは一般にAX + BY = Cの形式を想定しています。ここで、A = 3、B = 5、C=10です。

今、私のプロローグプログラムで、上記のクエリで言及された式を取り入れることができる述語を定義しようとしています。つまり、どういうわけか、A、B、Cの値と、関連する演算子(上記の場合はplus演算子)を格納して、プログラムで定義したロジックで使用したいと考えています。どうすればこれができるのだろうか。

より一般的に言うと、問題は、ゴール/クエリを介して渡される方程式に関係する定数と演算子をどのように識別するかということです。

4

4 に答える 4

2

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構文が使用されているため、変数や定数などを識別するために通常のビルトインを適用できます。

于 2012-02-05T16:50:46.013 に答える
1

次のトランスクリプトは、光を当てることができるかもしれません。

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 

最後のクエリは次のようになります。Term与えられたように、の1番目argは、のファンクターTermはアリティを持ち(つまり、args-subparts-それ自体を持ちます)、inの用語の2番目はnameで格納されます。明確にするために、Prologのシンボリックデータは、ファンクターと呼ばれる名前の形式であり、その式の「引数」には、呼び出しを通じてアクセスできます。Val1Val1F1A1A1argVal1Val12fff(aa,bb,cc,...)fffarg

つまり、元の式(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

乗算記号を明示的に書き出さないことを主張する場合は*、用語を文字列として表現し、その文字列を分析する必要があります。それははるかに複雑な作業になります。

編集:試してみるもう1つのことは=..、「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
于 2012-02-04T21:29:34.073 に答える
1

たとえば、用語検査述語を使用できます:arg / 3、functor / 3、var / 1、(= ..)/2など。

于 2012-02-04T18:11:14.350 に答える
0

用語書き換えルールを使用して実装されたシンボリック微分の例を確認することをお勧めします。彼らはそのような表現を扱います。

これがあなたが役に立つと思うかもしれない本ClausesandEffectからの章(マイナス1ページ)です: Clause and Effect-Chapter Six:Term Rewriting

The art of Prologのもう1つ:高度なプログラミング手法 23方程式ソルバー

Prologでのプログラミングには、記号微分に関するセクション(7.11)もあります。

于 2012-02-04T20:52:48.207 に答える