# How does one check a list for \_?

**URL:** <https://swi-prolog.discourse.group/t/how-does-one-check-a-list-for/5408>\
**Category:** Help!\
**Tags:** on-topic-only\
**Created:** [May 19, 2022, 10:53am UTC](https://swi-prolog.discourse.group/t/how-does-one-check-a-list-for/5408 "2022-05-19T10:53:29Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [May 19, 2022, 10:53am UTC](https://swi-prolog.discourse.group/t/how-does-one-check-a-list-for/5408/1 "2022-05-19T10:53:29Z")

</div>

In needing a set type (think has\_type/2) that is more rigours than ordered list, e.g. list\_to\_set/2, the list must not allow the use of `_`.

How does one check a list for `_`?

* * *

> **Details (Click triangle to expand)**
>
> In other words with creating a set from a list (list\_to\_set/2) this is acceptable
> 
> ```prolog
> ?- list_to_set([a],Set).
> Set = [a].
> 
> ?- list_to_set([a,a],Set).
> Set = [a].
> 
> ?- list_to_set([a,A],Set).
> Set = [a, A].
> 
> ?- list_to_set([A,A],Set).
> Set = [A].
> 
> ```
> 
> but this is not
> 
> ```prolog
> ?- list_to_set([_,_],Set).
> Set = [_, _].
> 
> ```
> 
> Thus an enhanced form of list\_to\_set/2 is needed for my case.
> 
> I am not asking for or abdicating that list\_to\_set/2 be modified in the SWI-Prolog system, my case just needs an additional guard for the type check to fail when a list has any `_` in it.

* * *

> **Personal notes (Click triangle to expand)**
>
> Prolog has some predicates for revealing properties of an entity. These predicates usually have the name property in them. There is one for variables, i.e. var\_property/2.
> 
> Thus using var\_property/2 was tried.
> 
> ```prolog
> ?- var_property(_,P).
> P = fresh(true) ;
> false.
> 
> ?- var_property(A,P).
> P = fresh(true) ;
> false.
> 
> ```
> 
> however it did not uniquely identify a `_` variable.
> 
> * * *
> 
> After reading [reply](https://swi-prolog.discourse.group/t/how-does-one-check-a-list-for/5408/2) from Jan W. tired.
> 
> ```prolog
> ?- ?=(_,_).
> false.
> 
> ?- ?=(A,A).
> true.
> 
> ?- ?=(_a,_a).
> true.
> 
> ?- ?=( __a,__ a).
> true.
> 
> ```
> 
> which reveals a means of checking for a difference in the kinds of variables.
> 
> * * *
> 
> To see the internal representation of a list with `_` write\_term/2 can be used.
> 
> ```prolog
> ?- L = [_,_,a,A,_a,_A, __a,__ A], write_term(L,[]).
> [_2708,_2714,a,_2726,_2732,_2738,_2744,_2750]
> L = [_, _, a, A, _a, _A, __a,__ A].
> 
> ```
> 
> * * *

* * *

After seeing [reply](https://swi-prolog.discourse.group/t/how-does-one-check-a-list-for/5408/2) from Jan W.

My concern for two `_` in a list converted to a set is unwarranted, the variables are different, e.g.

```prolog
?- list_to_set([_,_],Set),write_term(Set,[]).
[_5734,_5740]
Set = [_, _]

```

as it is the internal representation that matters not the user friendly representation.

---

<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 19, 2022, 11:19am UTC](https://swi-prolog.discourse.group/t/how-does-one-check-a-list-for/5408/2 "2022-05-19T11:19:35Z")

</div>

In Prolog you only have variables that maybe different or aliased. `_` is just a concept of read\_term/2 which makes variables that have the same name be the same variable except for `_`, which produces a new variable for every occurrence.

So, `[_|_]` is exactly the same as `[_1, _2]` (using numeric syntax to avoid the discussion about singleton/multiton).

list\_to\_set/2, like sort/2 and the ord\_\* predicates all compare terms based on the _standard order of terms_. This means that only terms that compare equal under `==/2` are removed. Further instantiation of elements may cause more elements to become equal under `==/2` _unless_ [?=/2](https://www.swi-prolog.org/pldoc/doc_for?object=?%3D%20/%202) is true for all pairs of the set. [?=/2](https://www.swi-prolog.org/pldoc/doc_for?object=?%3D%20/%202) is true if the two arguments are equal or can never become equal.

---

<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, 2022, 12:25am UTC](https://swi-prolog.discourse.group/t/how-does-one-check-a-list-for/5408/3 "2022-05-20T00:25:24Z")

</div>

I think what you’re looking for is a verification that no two items in the list can ever be instantiated in such a way that their ordering changes (e.g., they currently do not compare equal under ==/2 but could unify with =/2).

You might be interestested in the [Special unification and comparison predicates](https://www.swi-prolog.org/pldoc/man?section=unifyspecial) and also in `\+ \+ X=Y`.
