0

「findall」なしで、これが行うことを実行する述語を実装する方法を誰かが知っていますか?大いに感謝する。

domains
    oferta =  rebaixat ; normal
    element = string
        list = element*
database
    producte (string, integer, oferta)
predicates
    nondeterm reduced2(list)

clauses

    producte("Enciam",2,rebaixat). 
    producte("Peix",5,normal).
    producte("Llet",1,rebaixat). 
    producte("Formatge",5,normal).

         reduced2(Vals):-
            findall(Val, producte(Val,_,rebaixat),Vals).
Goal
    write("Amb findall"),nl,
    reduced2(List).
4

1 に答える 1

0

Visual Prolog についてはよくわかりませんが、一般的な回答をしようと思います。findall/3ただし、特定のケースの代替品を見つけたいのか、一般的なものを見つけたいのかによって異なります.

特定のケースでは、アキュムレータを使用できます。あなたの場合、これは、値が見つかったときに値が追加されるリストになります。何かのようなもの:

acc(In, List) :-
   ... % do something to generate possible next value
   ... % test if value is already in list In
   !,
   Out = [Val|In], % adds to the head, but is faster than using append
   acc(Out, List).
acc(List, List).

つまり、別の可能な値が見つからない場合は、見つかった値のリストを返します。多くの値を蓄積する必要があり、次の可能な値の生成がバックトラッキングによって行われる場合、これは遅くなる可能性があることに注意してください。また、これでは重複を生成できないため、findall/3.

の一般的な置き換えが必要な場合findall/3は、目標と、累積するインスタンスを含む変数または項を指定できますが、ある種の非論理グローバル変数を使用して回避することはできません。次の値を見つけたら、それをグローバル変数に格納されているものに追加し、バックトラックを発生させます。次の値の生成に失敗した場合は、グローバル変数の内容を取得して返します。

于 2012-01-09T17:47:47.660 に答える