Tuple terme construction avec l'opérateur ,/2
est généralement droit associatif en Prolog (généralement appelée une séquence ), de sorte que votre entrée a, b(c), d(e(f)), g
pourrait bien effectivement être le terme (a, (b(c), (d(e(f)), g)))
. Ceci est démontré par le fait que votre prédicat test2/1
imprimé ce qui est indiqué dans votre question, où le premier appel de la première clause de test2/1
, X
en correspondance a
et Xs
en correspondance (b(c), (d(e(f)), g))
, puis sur la deuxième invocation X
assortie b(c)
et Xs
assorti (d(e(f)), g)
, etc.
Si vous voulez vraiment faire face à une liste des termes interprétés comme une conjonction, vous auriez pu utiliser les éléments suivants:
test2([X|Xs]) :- write(X), nl, test2(Xs).
test2([]).
... sur l'entrée [a, b(c), d(e(f)), g]
. La structure de liste ici est généralement interprétée un peu différemment des tuples construits avec ,/2
(comme, au moins dans SWI-PROLOG, de telles structures sont du sucre syntaxique pour traiter des termes construits avec ./2
de la même manière que vous construiriez des séquences ou des tuples termes avec ,/2
). De cette façon, vous obtenez les avantages de la prise en charge des termes de liste, si vous pouvez autoriser les termes de liste à interprétés comme des conjonctions dans votre code. Une autre alternative consiste à déclarer et utiliser votre propre (peut-être opérateur infixe) pour la conjonction, comme &/2
, que vous pouvez déclarer:
:- op(500, yfx, &). % conjunction constructor
Vous pouvez ensuite construire votre conjoint comme a & b(c) & d(e(f)) & g
et traiter de manière appropriée de là, sachant exactement ce que vous entendez par &/2
- conjonction.Voir la page de manuel pour op/3
dans SWI-PROLOG pour plus de détails - si vous n'utilisez pas SWI, je présume qu'il devrait y avoir un prédicat semblable dans n'importe quelle implémentation PROLOG que vous utilisez - si ça vaut le coup: -)
EDIT: pour convertir un terme tuple construit à l'aide ,/2
à une liste, vous pouvez utiliser quelque chose comme ce qui suit:
conjunct_to_list((A,B), L) :-
!,
conjunct_to_list(A, L0),
conjunct_to_list(B, L1),
append(L0, L1, L).
conjunct_to_list(A, [A]).
Vos réponses post pourquoi est-ce travail de construction (,/2 opérateur) mais je ne sais toujours pas si c'est la bonne façon de gérer cette entrée. Le problème est que je ne peux pas traiter une liste de termes parce que je reçois le tuple en entrée. Peut-être qu'il y a un moyen de convertir un tuple en liste? Pourtant, je pourrais faire quelque chose comme ça: convertir ((X, Xs), [X | R]): - convertir (Xs, R). convertir (X, [X]). – milosz
J'ai ajouté 'conjunct_to_list/2' qui devrait aider à convertir un terme construit avec',/2' en une liste ('./2'). – sharky
Vous auriez pu écrire le premier comme ceci 'conjunct_to_list ((A, B), [A | T]): -!, Conjunct_to_list ((B), T) .'. Mais n'y a-t-il pas moyen de le faire sans '!'? – ohcibi