Prolog, geri dönmeden özyinelemeli çağrıyı sonlandırıyor gibi görünüyor

0

Soru

Aşağıdaki iki kenarı tanımladım:

edge(a,b).
edge(b,c).

add(X, L, [X | L]).

Şimdi bunu kullanarak yinelemeli olarak a'dan c'ye (a,b,c) giden yolu oluşturmaya çalışıyorum:

path(FROM,TO,W):-
    edge(FROM,TO),
    add(TO, [], X),
    add(FROM, X, W).
path(FROM,TO,W):-
    edge(FROM,Y),
    path(Y,TO, W),
    add(FROM, W, _).

Temel durumda iyi çalışıyor gibi görünüyor path(a,b,X) çıkış olacak X = [a,b]. Ancak, path(a,c,X) sadece çıkışlar X = [b,c] sanki sadece temel vakaya ulaşıyor ve özyinelemeli çağrıyı yedeklemek yerine orada bitiyor gibi. Sonuçta, çıktısını almak istiyorum X = [a,b,c] ama fikirlerim tükendi.

Bilgin olsun, SWİ-Prolog kullanıyorum.

prolog
2021-11-23 21:03:28
2

En iyi cevabı

1

Sorunu kendiniz nasıl tanımlayabilirsiniz? Bunu yapmak için kolay bir yoludur. İlk olarak, doğru olmasını beklediğiniz vakaları ve başarısız olmasını beklediğiniz vakaları belirleyin. Hata ayıklamayı kolaylaştırmak için bazı artı bazı yardımcı tanımlar

:- initialization(path(a,b,[a,b])).
:- initialization(path(a,c,[a,b,c])).   % intended to be true, initially false
:- initialization(\+path(a,b,[a,_,c])).
:- initialization(\+path(a,d,_)).       % no node d, thus no path

:- op(950, fy, *).
:- meta_predicate(*(0)).

*_G_0.   % this permits us to remove goals by adding a * in front.

Şimdi programı kaydedin ..ve söyle [program]. Aşağıdaki gibi bir uyarı alacaksınız

* user:user:path(a,c,[a,b,c]) - goal failed

Bu yüzden sorunu çözmediğimizi biliyoruz.

Şimdi, programı ekleyerek genelleştirmeye çalışın * bir golün önünde. Bu tür genellemelerin her biri için daha fazla hata görüneceğini (ve bir durumda sonlandırılmadığını) not edeceksiniz. Her şeyin aynı kaldığı son hedef hariç. Bu nedenle, bu hedefi kaldırmak veya değiştirmek iyi bir fikir gibi görünüyor.

Er ya da geç döngülerle karşılaşacaksınız. Asiklik yollar için şunları kullanınpath/4:

?- path(edge, Path, A, B).
2021-11-24 18:06:52
0

Alt hedef tarafından üretilen sonucu atar, çünkü kodunuz düzgün çalışmıyor add(FROM, W, _). yüklemin ikinci maddesinde path/3. Sorunu çözmek için kodunuzu aşağıdaki gibi değiştirmeniz gerekir:

path(From, To, W):-
    edge(From, To),
    add(To, [], X),
    add(From, X, W).

path(From, To, PATH):-   
    edge(From, Y),
    path(Y,To, W),
    add(From, W, PATH). % <== get PATH

Bu kodun daha da iyi bir sürümü aşağıdaki gibidir:

path(From, To, [From, To]) :-
    edge(From, To).

path(From, To, [From|Path]) :-
    edge(From, X),
    path(X, To, Path).
2021-11-24 13:56:11

Efsane, teşekkürler!
Dragonslayer

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................