# Detect type when target is a list with an unground tail?

**URL:** <https://swi-prolog.discourse.group/t/detect-type-when-target-is-a-list-with-an-unground-tail/947>\
**Category:** Help!\
**Created:** [July 14, 2019, 3:31am UTC](https://swi-prolog.discourse.group/t/detect-type-when-target-is-a-list-with-an-unground-tail/947 "2019-07-14T03:31:45Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![prodog](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@prodog](https://swi-prolog.discourse.group/u/prodog)\
**Post date:** [July 14, 2019, 3:31am UTC](https://swi-prolog.discourse.group/t/detect-type-when-target-is-a-list-with-an-unground-tail/947/1 "2019-07-14T03:31:45Z")

</div>

I’m using: SWI-Prolog version 8.1.9.

How can I tell if something is a list when it has a tail that is not ground? `is_list` and `is_of_type` both return false if the list has an unground tail, which means I can’t use them with difference lists.

```prolog
[debug] 16 ?- is_of_type(list, [a|T]).
false.

[debug] 19 ?- is_list([a|T])
false

```

---

<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:** [July 14, 2019, 4:46am UTC](https://swi-prolog.discourse.group/t/detect-type-when-target-is-a-list-with-an-unground-tail/947/2 "2019-07-14T04:46:41Z")

</div>

Try this definition for `is_list`:

```prolog
is_list(X) :-
    freeze(X, is_list2(X)).

is_list2([]).
is_list2([_|Xs]) :-
    is_list(Xs).

```

e.g.:

```prolog
?- X = [1,2,|Y], is_list(X), Y = [].

```

I’ll leave it as an “exercise for the reader” as to why your original `is_list` failed. (Hint: should it have succeeded? If so, what about `X = [1,2|Y], is_list(X), Y = 3`?)

---

<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:** [July 14, 2019, 8:15am UTC](https://swi-prolog.discourse.group/t/detect-type-when-target-is-a-list-with-an-unground-tail/947/3 "2019-07-14T08:15:27Z")

</div>

A list is defined as ending in `[]`. If it ends in something else it is not a list. It may be a _partial list_ or, more in general, terms may be of some _partial type_. This means the term is a _generalization_ of an instance of that type. The current library(error) has no support for partial types.

So, your only way out is to walk the list, finding the first non `[_|_]` cell and test it for being a variable.

Somewhere in my archives I have code that does something related to @peter.ludemann’s suggestion: if a term is a partial _something_, add constraints to the variables that force the term to remain compatible with the indicated type. I think there is some potential in this notion, but I never found the time to deeply look into it.
