2017-12-06 6 views
1

私はゴールでバックグラウンドをトリガーしようとしていますが、可能な場合は動的に行います。Prolog - 一連の動的オプションをバックトラックする

num(1). 
num(2). 
num(3). 
num(4). 
num(5). 

は、その後、私はSWI-Prologのに向かうと呼ん:良く例示するために、私の問題は、我々は以下のPROLOGコードを持っているとしましょうnum(X)を。 ;と入力すると、すべてのソリューションを探すバックトラッキングがトリガーされます。

私が望むのは、それらの事実(num(1)num(2)など)を削除し、それらの事実を動的に生成するもので置き換えることです。私がこれを達成できる方法はありますか?一種のもの、おそらく?

num(X):- for X in 1..5 

上記のコードと同じ解決策が得られますか?

私が知る限り、findall述語は私が探しているものではないリストを返します。私はすべての答えをバックトラックして、コンソールで;を使って調べます。

+0

私は重複しているとは思わない。私が知る限り、 'findall'はリストを返します。コンソールで ';'を使って一連の解決策を取り戻したいと思います。私は自分自身をうまく説明したいと思います。 – Ryncops

+1

コンソールで 'member(X、[1,2,3,4,5])。 'と入力するとどうなりますか? –

+0

@TomasBy素晴らしい、ありがとう!それでおしまい! – Ryncops

答えて

2

はい、あなたはすでに非常に近いです!

:- use_module(library(clpfd)). 

num(X) :- 
    X in 1..5. 

?- num(X). 
    X in 1..5. 

?- num(X), X #>3. 
    X in 4..5. 

?- num(X), labeling([], [X]). 
    X = 1 
; X = 2 
; X = 3 
; X = 4 
; X = 5. 
+1

それはスズメを撃つ大砲です:-P。 –

+0

非常に感謝しています!ご協力ありがとうございました! – Ryncops

0

SWI-Prologのは、そのための(非ISO)述語between/3があります

num(X) :- between(1, 5, X). 

あなたはこのように(他のプロローグのために、さらに微調整のため)述語を実装できます。

between2(A, A, A) :- !. % green cut 
between2(A, B, A) :- A < B. 
between2(A, B, C) :- 
    A < B, 
    A1 is A + 1, 
    between2(A1, B, C). 

between/3between2/3の両方の署名は(+From,+To,?X)です。これは、FromToがバインドされていなければならず、Xがバインドされているかどうかを意味します。 FromToは、From <= Toのような整数でなければなりません。 (ああ、これらの整数は、前にオプションのプラス記号またはマイナス記号をつけてアラビア数字を使って書かなければならず、ASCIIを使って書かなければなりません。通常は無制限の整数サポートでコンパイルされるため、通常between(1, 100000000000000000000000000000000000000000000, X)between2(1, 100000000000000000000000000000000000000000000, X)の両方が動作します)。

+2

'between(1、To、I)'は 'To = 1、I = 1'に対してのみ成功します。しかし、To = 2、I = 2、(1、To、I)の間でも成功する。だからそれはまったく緑のカットではありません。 – false

+0

@false提供されたリンクに 'between/3'の署名がありますか?彼らが質問されているように、「From」と「To」はバインドされなければなりません。あなたは '(1、2、X)'や '(5、1、X)'の間や '(1.5,3、X)'の間が「期待どおり」に動作しない理由を文句を言ってもいいかもしれません。 –

+0

あなたの答えに署名はありません! – false

関連する問題