2010-06-10 3 views
0

J'essaie de formater un résultat à partir d'un programme, mais j'ai du mal à le faire.Concaténation de terme Prolog

Je voulais donner quelque chose comme ceci comme résultat:

Res = do(paint(x) do(clean(a), do(repair(b) , initialState))) 

essentiellement, je veux concaténer termes successifs à initialState atome mais, il ne fonctionne pas avec atom_concat puisque les autres termes de concaténer ne sont pas atomes et aussi je voulais ajouter le) chaque fois que je passe par la fonction "faire". Donc, ce serait quelque chose comme: Res = initialState.

Lorsque la fonction a été appelée faire, je l'aurais fonction comme

concatenateTerm(Pred, Res, Res). 

Pred beeing réparation (b) par exemple, et obtenir le résultat: res = do(repair(b), initialState).

Est-ce possible?

Merci

+0

Probablement je ne vous comprends pas, mais ... Je suppose que vous voulez dire 'concatenateTerm (Pred, Res, ResNext)'. Dans ce cas, définissez-le comme 'concatenateTerm (A, B, faire (A, B)).'. – ony

+0

mais concatenateterm ne me donnerait pas res en conséquence. Je pourrais faire Temp = Res, puis appeler concatenateTerm (Pred, Temp, Res), qui concaténerait Pred avec Temp et donnerait le résultat sur Res mais encore une fois, il ne fonctionne pas avec atom_concat car il échoue avec des termes non atomiques. et aussi il ne serait pas ajouter le) à la fin. – d0pe

+0

Vous souhaitez construire un terme compliqué à partir de termes plus simples? –

Répondre

1

Si je vous comprends bien, vous devez faire quelque chose comme:

Res0 = initialState, 
do(repair(b), Res0, Res1), 
do(clean(a), Res1, Res2), 
do(paint(x), Res2, Res3), 

où vous résultat final est en Res3. Rappelez-vous que les procédures prolog ne "retournent" rien et que les valeurs d'entrée et de sortie doivent être passées par des arguments. Pourquoi voulez-vous concaténer des termes successifs à l'atome initialState? Ce n'est pas la façon prologue. Il serait beaucoup plus naturel en prologue de construire une structure qui est modifiée à chaque fois.

+0

De même que prolog ne "retourne" pas, il ne "modifie" pas non plus (sauf cas particuliers liés aux prédicats dynamiques, mais le remplacement de certains prédicats est aussi une mauvaise approche). La seule chose qui peut ressembler à une "modification" (mais qui ne l'est pas) consiste à utiliser des variables partiellement liées, dont certaines parties sont liées à une autre variable liée partiellement (par exemple 'Res3 = do (paint (x) , Res2), Res2 = faire (nettoyer (a), Res1), Res1 = faire (réparer (b), Res0), Res0 = état initial »ou« membre ((rouge = bleu), X), membre ((bleu = rouge), X) '). Mais de toute façon dans votre exemple vous n'avez pas de * concaténation * de termes, seulement appelez 'do/3' – ony

+0

@ony Désolé, cela a manqué. Bien sûr, il y a concaténation des termes. Quand 'do/3' fait quoi que ce soit, il ajoute plus d'informations à son terme" input ", le deuxième argument et le" renvoie "en le liant à son troisième argument. Ainsi, la valeur liée à 'Res0' est modifiée et liée à' Res1' qui est ensuite modifiée et liée à 'Res2' qui est modifiée et liée à' Res3'. Ce * chaînage * des données via les variables est courant dans Prolog et la dénomination de la variable l'indique. 'Res0' ->' Res1' -> 'Res2' ->' Res3' – rvirding

-1

@ d0pe, il n'y a aucun résultat en Prolog (ils existent dans Mercure et Erlang, je suppose) il n'y a que des valeurs nommées qui spécifiaient/unifié dans la tête et probablement plus tard dans le corps unifiés. L'exécution de Temp = Res, concatenateTerm (Pred,Temp, Res) échouera dans la plupart des cas car Temp = Res, Res = do(Pred, Temp) produira un terme infiniment récursif do(Pred, do(Pred, do(Pred, ...))) (lorsque l'extension appropriée est disponible). Je suppose que ce n'est pas ce que tu veux.
Mais maintenant, je comprends que vous voulez modifierRes - c'est une mauvaise compréhension de Prolog. Il n'y a pas de variables, vous devez utiliser la prochaine approche Res0 = initialState, Res1 = do(repair(b), Res0), Res2 = do(clean(a), Res1), Res3 = do(paint(x), Res2).

Probablement votre règle ressemblera (voir des exemples de singe + bananna en Prolog):

solve(FinalState, finish, FinalState). % our initial state is our goal 

solve(InitState, do(Action, Future), FinalState):- 
    action(InitState, Action, NewState), 
    solve(NewState, Future, FinalState). 
+0

Je crois que @ d0pe vient de demander comment _construire un terme pour mettre en forme une sortie _... pourquoi es-tu (plutôt confus) en train de parler de termes infiniment récursifs et de modifier des variables liées? – sharky

+0

@rati, et j'ai fait savoir comment * construire un terme *. Les termes récursifs et les variables liées modifiantes sont mentionnés en raison de "Donc ce serait quelque chose comme:" et "Res = initialState, concatenateTerm (Pred, Res, Rés), Pred = réparation (b)' et attend 'Res = do (réparation (b), initialState) 'qui ressemble à @ chose d0pe que concatenateTerm devrait prendre" first "' Res' concaténer 'repair (b)' et le renvoyer comme "second" 'Res'. – ony

1

Je suis d'accord avec @rvirding dans que vous aurez juste besoin de construire un terme comme résultat PROLOG , au lieu d'essayer de construire un atome . Même si vous essayez ce dernier (ce qui est en effet possible), vous pouvez généralement convertir des atomes en termes et revenir en utilisant des fonctions utilitaires (telles que atom_to_term/3 ou term_to_atom/2 dans SWI-PROLOG), si besoin est.

Quoi qu'il en soit, un simple prédicat de prendre toute une liste de termes « d'État » et la production d'un tel terme que vous avez décrit précédemment pourrait ressembler à ceci:

build_do_term([X,Y], do(X,Y)) :- !. 
build_do_term([X|Xs], do(X,Rem)) :- 
    build_do_term(Xs, Rem). 

Appeler ce prédicat sur les termes de l'État (dont il doit y avoir au moins deux):

?- build_do_term([paint(x), clean(a), repair(b), initialState], Rem). 
Rem = do(paint(x), do(clean(a), do(repair(b), initialState))). 

... qui reflète le comportement que vous avez décrit comme après. Si vous ne souhaitez pas créer le terme en une seule fois à partir d'une liste, vous pouvez toujours utiliser la méthode de construction de terme do/2 utilisée dans build_do_term/2 ci-dessus dans votre propre code pour construire le terme approprié do/2 si nécessaire.

+0

comment avez-vous deviné que @ d0pe déjà * concaténé * termes dans la liste '[paint (x) | [nettoyer (a) | [... | []] ..] 'qui est exactement le même problème que * concaténation * avec' do/2'? – ony

+0

Je ne devinais pas ou ne supposais rien sur le code avec lequel @ d0pe travaillait. Le but de l'utilisation de la structure de liste ici en entrée de 'build_do_term/2' est d'illustrer, de façon simple, comment un prédicat PROLOG pourrait être implémenté pour construire le terme (supposé) nécessaire 'do/2', comme décrit, comme un guide, puisque d0pe voulait quelque chose comme 'concatenateTerm/3'. Je pense que cela est clair à partir de ma dernière déclaration dans le post ...: - \ – sharky