# Rename specific variables in a term with new names

**URL:** <https://swi-prolog.discourse.group/t/rename-specific-variables-in-a-term-with-new-names/3976>\
**Category:** Help!\
**Tags:** how-to\
**Created:** [May 20, 2021, 3:13pm UTC](https://swi-prolog.discourse.group/t/rename-specific-variables-in-a-term-with-new-names/3976 "2021-05-20T15:13:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![niteshroyal](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/niteshroyal/32/1666_2.png) [@niteshroyal](https://swi-prolog.discourse.group/u/niteshroyal)\
**Post date:** [May 20, 2021, 3:13pm UTC](https://swi-prolog.discourse.group/t/rename-specific-variables-in-a-term-with-new-names/3976/1 "2021-05-20T15:13:06Z")

</div>

Hello,

I want to write a predicate `rename_term_variables/3`, which takes a term and a list of certain variables in the term as input and should output a new term where the variables in the list are renamed.

The following example illustrates the desired output of the predicate:

```prolog
?- rename_term_variables(a(X, b(X, Y, Z)), [X,Z], New_Term).

New_Term = a(_7448, b(_7448, Y, _7450)).

```

Can anyone tell me how to write such a predicate?

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [May 20, 2021, 3:48pm UTC](https://swi-prolog.discourse.group/t/rename-specific-variables-in-a-term-with-new-names/3976/2 "2021-05-20T15:48:08Z")

</div>

Not quite sure what you’re asking, but you might be interested in the `variable_names` option of read\_term/2 and write\_term/2. Also the numbervars/1 predicate and the `numbervars` options of write\_term/2.

---

<div class="post-metadata">

**Author:** ![niteshroyal](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/niteshroyal/32/1666_2.png) [@niteshroyal](https://swi-prolog.discourse.group/u/niteshroyal)\
**Post date:** [May 20, 2021, 5:31pm UTC](https://swi-prolog.discourse.group/t/rename-specific-variables-in-a-term-with-new-names/3976/3 "2021-05-20T17:31:20Z")

</div>

Peter,

Thanks for suggesting to use the `numbervars/1` predicate. The following code works for me:

```prolog
rename_term_variables(Term, Vars, New_Term) :-
	numbervars(Vars),
	New_Term = Term.

?- rename_term_variables(a(X, b(X, Y, Z)), [X,Z], New_Term).
X = A,
Z = B,
New_Term = a(A, b(A, Y, B)).

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [May 20, 2021, 6:07pm UTC](https://swi-prolog.discourse.group/t/rename-specific-variables-in-a-term-with-new-names/3976/4 "2021-05-20T18:07:21Z")

</div>

The quick way probably goes along this route:

- use term\_variables/2 to get the vars of the term
- use copy\_term/2 to get a fresh fully separate copy.
- use term\_variables/2 on the copy to get the vars of the term
- unify the variables of the copy that need not be renamed.

---

<div class="post-metadata">

**Author:** ![niteshroyal](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/niteshroyal/32/1666_2.png) [@niteshroyal](https://swi-prolog.discourse.group/u/niteshroyal)\
**Post date:** [May 20, 2021, 8:33pm UTC](https://swi-prolog.discourse.group/t/rename-specific-variables-in-a-term-with-new-names/3976/5 "2021-05-20T20:33:55Z")

</div>

Thanks, Jan, that works.

Here is the code that works:

```prolog
rename_term_variables(Term,V,New_Term) :-
	term_variables(Term, V1),
	copy_term(Term, New_Term),
	term_variables(New_Term, V2),
	unify_var(V,V1,V2).

unify_var(_,[],[]) :- !.
unify_var(V,[H1|T1],[H2|T2]) :-
	( \+needed_var(H1,V) ->
		H2 = H1
	;	true
	), unify_var(V,T1,T2).

needed_var(_,[]) :- fail.
needed_var(H,[HV|TV]) :-
	( H == HV ->
		!
	;	needed_var(H,TV)
	).

?- rename_term_variables(a(X, b(X, Y, Z)), [X,Z], New_Term).
New_Term = a(_3306, b(_3306, Y, _3316)).

```
