Prolog zdánlivě končí rekurzivní volání, aniž by zpět nahoru

0

Otázka

Mám následující dvě hrany definice:

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

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

Teď se snažím rekurzivně vytvořit cestu z a do c (a,b,c) pomocí této:

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, _).

Zdá se, že funguje dobře v základní věci jako path(a,b,X) bude výstup X = [a,b]. Nicméně, path(a,c,X) pouze výstupy X = [b,c],, jako kdyby to prostě dostane na základní případ, a končí to tam, spíše než jít zpátky do rekurzivní volání. Nakonec, rád bych, aby výstup X = [a,b,c] ale už mi došly nápady.

FYI jsem pomocí SWI-Prolog.

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

Nejlepší odpověď

1

Jak můžete identifikovat problém sami? Tam je snadný způsob, jak tak učinit. Za prvé, určit případy, které byste očekávat, že bude pravda, a případech, můžete očekávat, že selhání. Zde jsou některé plus nějaké pomocné definice pro snadné ladění

:- 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.

Nyní uložte program ..a říct [program]. Zobrazí se varování, jako

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

Takže víme, že máme problém nevyřešilo.

Nyní, pokusit se zobecnit přidáním programu * před brankou. Všimněte si, že pro každé takové zobecnění, že tam bude více chyb se objeví (a v jednom případě dokonce i non-ukončení). Až na poslední branku, kde vše zůstává stejné. Takže odstranění nebo nahrazení tohoto cíle se zdá být dobrý nápad.

Dříve nebo později se setkáte s cykly. Pro acyklické cesty, použití path/4:

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

Váš kód nefunguje správně, protože to zbavuje výsledek produkovaný subgoal add(FROM, W, _)v druhé klauzule predikátu path/3. Vyřešit problém, budete muset upravit kód takto:

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

Ještě lepší verze tohoto kódu je následující:

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

Legenda, děkuji!
Dragonslayer

V jiných jazycích

Tato stránka je v jiných jazycích

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