2017-02-06 15 views
1

述語が同じ情報で既に存在するかどうかをテストして、同じ情報を再度入力できないようにすることができるかどうかは疑問でした。プロローグが重複する述語を避ける

は、私はすでに、単一の述語のためにそれを行うために管理していない:

:- dynamic(test/2). 

test(a,b). 

top(X,Y) :- 
    (test(X,Y), 
    write('Yes'),! 
    ;write('No'),! 
    ). 

このバージョンは戻って、うまく動作します「はい」の情報がすでに存在している場合「NO」そうでない場合。

私は、 'test/2'だけでなく、複数のprediactesに対してこれを行うことが可能かどうか疑問に思っていました。 述語 'test'を変数Predに置き換えようとしましたが、残念ながらコンパイルしようとすると構文エラーが発生します。

main(Pred,X,Y) :- 
     (Pred(X,Y), 
     write('Yes'),! 
     ;write('No'),! 
    ). 

が、このような何かをすることも可能であり、それがある場合にどのようにそれは可能でしょう:ここに は私の試みですか?

Btw私はGNU Prologを使用しています。

大変ありがとうございます:D !!

+1

が、それはすべきではないが、 ' - >'されたif-then-elseで? –

+0

述語の存在を確認していません。特定のクエリまたは事実が真で正しいかどうかを確認していますか?'Pred'が述語として存在するかどうかを調べることは一つですが、' test(X、Y) '(あるいは' call(Pred、X、Y) ')が特定の' /または 'Y'。 – lurker

答えて

2

call/2は、実行時に評価された引数付きの動的目標を呼び出すようにします。あなたのケースでは、それは、call(Pred,X,Y)次のようになります。

main(Pred,X,Y) :- 
    (
     call(Pred,X,Y), 
     write('Yes'),! 
    ) 
    ; 
    (
     write('No'),! 
    ). 

Pred/2は、実行時に実際の述語に解決しなければならない、とあなたは、引数の数ごとに異なるルールを構築する必要があることに注意してください。 (=..)/2を使用して

トマス・バイの答え@

は、あなたが引数のリストで、単一のルールを作成できますが、余分なラインとはいえ、既存の述語に関する同じ警告を持つ:

main(Pred,L) :- % where L is a list of args [X,Y|...] 
    Term =.. [Pred | L], 
    (
     Term, 
     write('Yes'),! 
    ) 
    ; 
    (
     write('No'),! 
    ). 

そして、として(->)/2を使用して、いずれの場合では、@lurkerのコメントで指摘:

(call(Pred,X,Y) -> write('Yes') ; write('No')) 

または

(Term -> write('Yes') ; write('No')) 
選択点の破壊がif-> then; else構造に限定されるので、

が望ましいかもしれません。

+0

私は 'p1 - > p2;を使うでしょう。 p3'構文のように動作します。 ; '(p1、!);を使用するのではなく、' p2'を使用します。 (p2、!) 'となる。 – lurker

+0

'clause/2'と' current_predicate/1'もすでに定義されているものを突き止めるのに使うことができます。 –

2

オペレータがあります= ..のように、用語を構築するための:

Term =.. [Op,V1,V2] 

それは、GNU Prologであるかどうかわかりません。 Sicstus使用

xxx(1,2). 

check(Pred,X,Y) :- 
    Term =.. [Pred,X,Y], 
    (Term -> 
    write('Yes') 
    ; write('No')). 

とファイルロードした後

| ?- check(xxx,1,2). 
Yes 
+0

私はあなたが気にしないことを願っていますが、私は答えをより完全にするために、自分の使った情報を私の答えに含めました。あなたが好きなら、私はそれを削除することができます。 –

関連する問題