1
sum([],0).
sum([H|T],S) :- sum(T,X),S is X+H.

mean([],0).
mean(L,M) :- sum(L,S),length(L,L1),M is S/L1.
:-arithmetic_function(mean/1).
when i try 
?- mean([1,2,3,4],X).

それは

X= 2.5 
Yes 

今、私は使いたい

?- X is mean ([1,2,3,4]. 

しかし、それは

Type error: ERROR: '.'/2: Type error: `[]' expected, found `[2, 3, 4]' ("x" must hold one character) 

リストで算術関数を使用するにはどうすればよいですか?

4

1 に答える 1

3

コードは正しい方向に進んでいるように見えますが、残念ながら、任意の長さの数値のリストを、のパラメーターなど、sとして定義された関数のパラメーター(引数)として使用できないようです。arithmetic_functionmean/1

この問題は、SWI-Prologでは、./2それ自体がこのコンテキストでは算術型と見なされるという事実に関連しているように見えます。

説明:

検討:

?- X is 1 + 2 * 3.
X = 7. 

算術演算子*はよりも優先されるため+、これは実際には次のようになります。

?- X is (1 + (2 * 3)).
X = 7. 

さらに、+*はバイナリ中置演算子であり、それ以外の場合は次のように記述できます。

?- X is '+'(1, '*'(2, 3)).
X = 7. 

ここで、SWI-Prologは実際、式ツリー「裏返し」を*最初に評価し、次にその結果を+式に適用していることに注意してください。これを念頭に置いて、次にあなたの例を考えてみましょう。

?- X is mean([1,2,3,4]).

SWI-Prologが実際に解釈するのは実際には次のとおりです。

?- X is mean('.'(1,[2,3,4])).

さて、'.'/2は算術型であるため、SWI-Prologは最初にこの式を評価します(上記の例のように)が、型チェックはそれが必要なパターン、つまり整数を含む長さ1のリストで*はないことを明らかにします(ドキュメントを参照).(+Int,[])上記のリンクの後ろ)。[]が等しくないため[2,3,4]、報告するタイプエラーが発生します。

次のことも検討してください。

?- X is mean([1]).

SWI-Prologが実際に解釈するのは実際には次のとおりです。

?- X is mean('.'(1,[])).

.(+Int,[])さて、これは型パターンの有効なインスタンスですが、この算術型のセマンティクスに従って、を与えるために評価*されます(上記で評価されたのとほぼ同じ方法で)。1次に、値1は、の実装の最初の入力引数にバインドされmean/2ます。それ以外の場合は、入力リストになります。

于 2011-01-05T11:15:02.703 に答える