2011-06-19 2 views
1

J'ai un terme, disons a(t1,t2,t3) que je variabilise en utilisant numbervars/3. Ensuite, je dois extraire les variables du terme, mais les variables apparaitront sous formeReprésentation variable

a('$VAR'(0),'$VAR'(1),'$VAR'(2)) 

Le problème est que prolog ne semble pas reconnaître ces termes comme variables:

?- term_variables(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),L). 
L = []. 

Ou encore plus simple :

?- var('$VAR'(0)). 
false. 

D'autre part, si je l'utilise copy_term/2, il voit les correctement des variables, mais toujours term_variables/2 ne les extraire:

?- copy_term(a('$VAR'(0),'$VAR'(1),'$VAR'(3)),Term),term_variables(Term,Vars). 
Term = a(A, B, D), 
Vars = []. 

Est-ce que quelqu'un a une idée de ce que je fais mal? Je suis vraiment coincé et je ne peux pas travailler plus loin dans le programme que je développe à cause de cela.

Merci beaucoup d'avance.

Répondre

4

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!).

+0

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

+0

Votre 'variablize' est un joli morceau de code. J'aimerais pouvoir atteindre ce niveau de compétence Prolog! – Jaywalker

+0

Merci! J'espère que c'est utile. J'ai programmé Prolog professionnellement à plein temps pendant plusieurs années;) – sharky