Je ne suis pas sûr de la façon dont vous utilisez numbervars/3
, qui est mis en œuvre de manière à « ... unifier les variables libres de [terme] un terme $VAR(N)
», qui ne peut être directement utilisé pour transformer le terme a(t1,t2,t3)
en a('$VAR'(0),'$VAR'(1),'$VAR'(2))
comme vous le suggérez, sauf si t1
, t2
et t3
sont vos place-titulaires pour des variables distinctes.
Les termes '$VAR'(N)
que numbervars/3
de SWI génère sont en effet termes, et non variables (décrites dans le manuel), ne peuvent donc pas être traités comme des variables.
Notez que, si vous voyez ceci:
?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term).
Term = a(A, B, D).
Ce qui se passe est que la ligne Term = a(A, B, D).
est en cours d'écriture par quelque chose comme write_term/2
à la console, qui peut être configuré pour représenter certains termes comme '$VAR'(N)
comme nom variables (qui peuvent être trompeuses). Notez que si vous essayez ceci:
?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term),
write_term(Term, [numbervars(false)]).
a($VAR(0), $VAR(1), $VAR(3))
Term = a(A, B, D).
L'appel à write_term/2
ici désactive explicitement l'option numbervars
et imprime les véritables fixations des arguments du terme a/3
, qui sont en effet $VAR(N)
termes. La ligne suivante imprimée sur la console (c'est-à-dire, Term = a(A, B, D)
) fait quelque chose de semblable à permettant à l'option numbervars
à la place (peut-être pour plus de lisibilité).
Si vous avez besoin de « variablize » un terme, je peux suggérer quelque chose dans ce sens au lieu:
% takes a term T, a list of [Term:Variable] replacements R, and makes V:
variablize(T, R, V) :-
member(R0:V, R),
R0 == T, !.
variablize([T|Ts], R, [NT|NTs]) :-
!,
variablize(T, R, NT),
variablize(Ts, R, NTs).
variablize(T, R, NT) :-
compound(T), !,
T =.. [F|As],
variablize(As, R, NAs),
NT =.. [F|NAs].
variablize(T, _, T).
Exemple:
?- variablize(a(t1,t2,t3), [t1:X, t2:Y, t3:Z], T).
T = a(X, Y, Z).
Cela suppose que vous savez quels sous-éléments (par exemple , t2
) que vous souhaitez remplacer et avec quelles variables.Cette implémentation particulière pourrait s'appeler plus précisément replace/3
, car elle trouvera et remplacera toute occurrence de sous-élément dans le terme d'entrée (même s'il s'agit d'autres variables!).
Merci beaucoup pour votre réponse. Ce que vous proposez n'aide pas beaucoup, puisque je ne connais pas le terme que je dois variabiliser. Je dois construire des clauses correspondant à un biais syntaxique de la connaissance, puis variabiliser et généraliser. J'utilise numbervars (_, N, _), où N est 0 pour la première variable et incrémenté pour chaque nouvelle, puis créer un terme varbed en utilisant les foncteurs initiaux. Mais j'ai besoin d'obtenir les variables à partir du terme variabilisé. J'ai recouru à une méthode stupide, en écrivant le terme varié dans un fichier, puis en le lisant et en obtenant les vars. Toutes les autres suggestions sont vraiment les bienvenues. – Nikos
Votre 'variablize' est un joli morceau de code. J'aimerais pouvoir atteindre ce niveau de compétence Prolog! – Jaywalker
Merci! J'espère que c'est utile. J'ai programmé Prolog professionnellement à plein temps pendant plusieurs années;) – sharky