1

だから私はSWI-PrologでいくつかのPrologをやっていて、ちょっとした問題に出くわしました。入力リストを指定して、キューブのリストを作成する必要があります。私が現在持っているコードは

cubes([Head|Tail],Cubes) :-
    cubes([Head|Tail],Cubes,[]).
cubes([Head|Tail],Cubes,ActualCubes) :-
    X is Head^3,
    append(ActualCubes,[X],NewCubes),
    cubes(Tail,Cubes,NewCubes).
cubes([Tail],Cubes,ActualCubes) :-
    X is Tail^3,
    append(ActualCubes,[X],NewCubes),
    Cubes is NewCubes.

私が実行すると、エラーが発生します。具体的には...

ERROR: '.'/2: Type error: `[]' expected, found `[8]' ("x" must hold one character)
   Exception: (7) cbList([1, 2], _G296, []) ? creep

このエラーが発生している理由は完全にはわかりませんが、最後の行で発生しているようです。CubesはNewCubesです。どんな助けでも大歓迎です:)

4

3 に答える 3

5

アキュムレータと呼ばれるパターンを実行して、中間結果を保持する引数を追加して2項関係を書き換えようとしていると思います。

構文エラーは別として、リストの各要素は他のリストの対応する要素との関係しているため、ここではアキュムレータは役に立たないことに注意してください。

library(apply)には、このような一般的なケースのマップリスト/3があります。

cube(N, C) :-
    C is N^3.
cubes(Ns, Cs) :-
    maplist(cube, Ns, Cs).

また、library(clpfd)には、(整数ドメインで)算術のより良いリレーショナル処理を可能にする興味深い機能があります。上記のキューブを次のように置き換えます

:- [library(clpfd)].

cube(N, C) :-
    N ^ 3 #= C.

そしてあなたは書くことが許されています

?- cubes(X,[1,8,27]).
X = [1, 2, 3].
于 2012-08-13T06:02:54.307 に答える
1

まず、cubes引数の数が異なるさまざまな述語を作成しています。これは、概念的な問題と構文上の問題の両方を引き起こすことになります。その時点で、何をしているのかを考え直してください。この場合、パターンマッチングと再帰を使用する方法を拡張してみてください。

cubes([],[]).
cubes([H|T], [Y|Z]):-
        Y is H*H*H,
        cubes(T,Z).


betterCubes([],[]).
betterCubes([H|T], [Y|Z]):-
        ( 
          var(Y) , nonvar(H)    -> Y is H*H*H
        ; nonvar(Y) , var(H)    -> H is Y**(1.0/3.0) 
        ; nonvar(Y) , nonvar(H) -> H*H*H =:= Y
        ),
        betterCubes(T,Z).
于 2012-08-13T01:45:35.167 に答える
-1

この場合、差分リストを使用して目的の目標を達成することもできます。

cubes( [] , [] ) .
cubes( [X|Xs] , [Y|Ys] ) :-
  Y is X*X*X ,
  cubes( Xs , Ys )
  .

出力リストは、ソースリストをトラバースしながら、下に向かって作成されます。最終的な目標cubes([],[])は、空のリスト[]を出力リストの末尾と統合して、正しいリストにします。

もう1つのアプローチは、アキュムレータを使用することです。アキュムレータは、出力を逆の順序で作成してから、逆にします。

cubes(Xs,Ys) :-
  cubes(Xs,[],T) ,
  reverse(T,Ys)
  .

cubes( [] , Ys, Ys ).
cubes( [X|Xs] , Ts , Ys ) :-
  T is X*X*X ,
  cubes( Xs , [T|Ts] , Ys )
  .

どちらも(そうあるべきですが)適切に末尾再帰です。

于 2012-08-14T19:34:02.067 に答える