2013-03-26 6 views
2

J'ai écrit quelques Prolog pour remplacer des éléments dans la liste deux avec un atome appelé empty si elles figurent dans la liste ci:Prolog variable inconnue sur append

replace_build([], _Inv, _Res). 

replace_build([A| B], Inv, Res) :- 
    replace_build2(A, Inv, Res), replace_build(B, Inv, Res). 

replace_build2(_BuildItem, [], _NewInv) :- !. 

replace_build2(BuildItem, [BuildItem| T], NewInv) :- 
    replace_build2(BuildItem, T, NewInv1), 
    append([empty], NewInv1, NewInv). 

replace_build2(BuildItem, [H| T], NewInv) :- 
    replace_build2(BuildItem, T, NewInv1), 
    append([H], NewInv1, NewInv). 

Cependant, quand je le lance, je reçois un variables inhabituelle anonyme (est que la terminologie correcte?) comme dans l'exemple suivant:

?- replace_build([item3], [empty, item5, item1, item3, empty], X). 
X = [empty, item5, item1, empty, empty|_G467] 

(! en outre, il resatisfies que je ne veux pas, même si je espère pouvoir travailler que sur)

Pourquoi le |_G467 dans la liste qui en résulte?

Répondre

2

problème un est cette clause:

replace_build2(_BuildItem, [], _NewInv) :- !. 

Vous pouvez y remédier en mettant un [] pour _NewInv:

replace_build2(_BuildItem, [], []) :- !. 

Le problème, il est juste que vous aviez une variable non être jointe à:

?- replace_build([item3], [empty, item5, item1, item3, empty], X). 
X = [empty, item5, item1, empty, empty] ; 
X = [empty, item5, item1, item3, empty]. 

La raison pour laquelle vous avez deux réponses est parce que les deux clauses de replace_build2 correspondent, ce qui explique pourquoi vous obtenez empty et item3 là. Prolog va heureusement unifier deux variables à la même valeur, et il n'y a rien ici pour arrêter BuildItem et H de faire référence à la même valeur. Vous devez dire explicitement Prolog que ce sont différents, donc changer votre clause replace_build2 finale à ceci:

replace_build2(BuildItem, [H| T], NewInv) :- 
    BuildItem \= H, 
    replace_build2(BuildItem, T, NewInv1), 
    append([H], NewInv1, NewInv). 

Maintenant, vous obtenez seulement la solution que vous voulez:

?- replace_build([item3], [empty, item5, item1, item3, empty], X). 
X = [empty, item5, item1, empty, empty] ; 
false. 

Vous pouvez également utiliser dif/2 dans certains Prologs.

2

Lorsque vous avez une tâche 'liste de transformation', avec une logique 'article à la fois' à gérer, vous pouvez utiliser maplist/N.

Puis

replace_build(Items, Inv, Res) :- 
    maplist(replace_build_item(Inv), Items, Res). 

replace_build_item(Inv, Item, Res) :- 
    memberchk(Item, Inv) -> Res = empty ; Res = Item. 

Mais pour apprendre Prolog, vous êtes sur la bonne voie, et Daniel bien expliqué au sujet de vos problèmes. Il est important de comprendre les tâches de traitement de liste de base!

Questions connexes