# Is there a has\_type/2 for difference list?

**URL:** <https://swi-prolog.discourse.group/t/is-there-a-has-type-2-for-difference-list/2622>\
**Category:** Predicate\
**Tags:** difference-list, has\_type2\
**Created:** [July 9, 2020, 10:17pm UTC](https://swi-prolog.discourse.group/t/is-there-a-has-type-2-for-difference-list/2622 "2020-07-09T22:17:49Z")\
**Posts on this page:** 1\
**Showing post:** 2

<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:** [July 10, 2020, 1:24am UTC](https://swi-prolog.discourse.group/t/is-there-a-has-type-2-for-difference-list/2622/2 "2020-07-10T01:24:35Z")

</div>

This is what I currently have. It has not been converted into has\_type/2 but that is just a wrapper for consistency and ease of using.

\*\* If you are up for a challenge you should try to do this for yourself. \*\*

It is a simple predicate that returns `true` or `false` with predicate indicator `list_difference(L1,L2)`.

> **Current code - click triangle to expand.**
>
> ```prolog
> list_difference(L1,L2) :-
> '$skip_list'(Length1,L1,_),
> '$skip_list'(Length2,L2,_), !,
> Length1 >= Length2,
> list_difference(Length1,Length2,L1,L2).
> 
> list_difference(Length,Length,L1,L2) :-
> \+ '$skip_list'(Length,L1,_),
> \+ '$skip_list'(Length,L2,_),
> ground(L1),
> ground(L2),
> L1 == L2, !.
> list_difference(Length,Length,L1,L2) :-
> '$skip_list'(Length,L1,_),
> '$skip_list'(Length,L2,_),
> ground(L1),
> ground(L2),
> L1 == L2, !.
> list_difference(Length,Length,L1,L2) :-
> var(L1),
> var(L2),
> L1 == L2, !.
> list_difference(Length10,Length2,L1,L2) :-
> Length10 > 0,
> Length1 is Length10 - 1,
> L1 = [_|T0],
> list_difference(Length1,Length2,T0,L2).
> 
> ```
> 
> No longer needing to tinker with it for corner cases. Also can probably reduce two of the clauses into one but it is late.

Example run.

```prolog
?- list_difference(A,B).
false.

?- list_difference([1|T1],T2).
false.

?- list_difference([1,2,3],[2]).
false.

?- list_difference(A,A).
true.

?- list_difference([],[]).
true.

?- list_difference([1|T1],T1).
true.

?- list_difference([1],[1]).
true.

?- list_difference([1],[]).
true.

?- list_difference([1,2],[]).
true.

?- list_difference([1,2],[2]).
true.

```

Still need to do a lot more test cases.

**EDIT**

New version passing more extensive test cases.

> **Code**
>
> ```prolog
> error:has_type(difference_list,(L1-L2)) :-
> difference_list_type_check((L1-L2)).
> 
> difference_list_type_check((L1-L2)) :-
> error:has_type(list_or_partial_list,L1),
> error:has_type(list_or_partial_list,L2),
> '$skip_list'(Length1,L1,_),
> '$skip_list'(Length2,L2,_), !,
> Length1 >= Length2,
> difference_list_type_check(Length1,Length2,L1,L2).
> 
> difference_list_type_check(Length,Length,L1,L2) :-
> ground(L1),
> ground(L2),
> L1 == L2, !.
> difference_list_type_check(Length,Length,L1,L2) :-
> var(L1),
> var(L2),
> L1 == L2, !.
> difference_list_type_check(Length10,Length2,[_|T],L2) :-
> Length10 > 0,
> Length10 > Length2, !,
> Length1 is Length10 - 1,
> difference_list_type_check(Length1,Length2,T,L2).
> difference_list_type_check(Length0,Length0,[H|T1],[H|T2]) :-
> Length0 > 0,
> Length is Length0 - 1,
> difference_list_type_check(Length,Length,T1,T2).
> 
> ```

> **Test cases**
>
> ```prolog
> :- begin_tests(difference_list).
> 
> % Turn off singleton variable warnings in this module.
> :- style_check(-singleton).
> 
> difference_list_type_check_test(success,01,(T1-T1)).
> difference_list_type_check_test(success,02,([1|T1]-T1)).
> difference_list_type_check_test(success,03,([1,2|T1]-T1)).
> difference_list_type_check_test(success,04,([1,2,3|T1]-T1)).
> difference_list_type_check_test(success,05,([1|T1]-[1|T1])).
> difference_list_type_check_test(success,06,([1,2|T1]-[2|T1])).
> difference_list_type_check_test(success,07,([1,2,3|T1]-[3|T1])).
> difference_list_type_check_test(success,08,([1,2|T1]-[1,2|T1])).
> difference_list_type_check_test(success,09,([1,2,3|T1]-[2,3|T1])).
> difference_list_type_check_test(success,10,([1,2,3,4|T1]-[3,4|T1])).
> difference_list_type_check_test(success,11,([1,2,3|T1]-[1,2,3|T1])).
> difference_list_type_check_test(success,12,([1,2,3,4|T1]-[2,3,4|T1])).
> difference_list_type_check_test(success,13,([]-[])).
> difference_list_type_check_test(success,14,([1]-[])).
> difference_list_type_check_test(success,15,([1,2]-[])).
> difference_list_type_check_test(success,16,([1,2,3]-[])).
> difference_list_type_check_test(success,17,([1]-[1])).
> difference_list_type_check_test(success,18,([1,2]-[2])).
> difference_list_type_check_test(success,19,([1,2,3]-[3])).
> difference_list_type_check_test(success,20,([1,2]-[1,2])).
> difference_list_type_check_test(success,21,([1,2,3]-[2,3])).
> difference_list_type_check_test(success,22,([1,2,3,4]-[3,4])).
> difference_list_type_check_test(success,23,([1,2,3]-[1,2,3])).
> difference_list_type_check_test(success,24,([1,2,3,4]-[2,3,4])).
> difference_list_type_check_test(success,25,([A|B]-B)).
> difference_list_type_check_test(success,26,([A|B]-[A|B])).
> difference_list_type_check_test(success,27,([A,B|C]-C)).
> difference_list_type_check_test(success,28,([A,B|C]-[B|C])).
> difference_list_type_check_test(success,29,([A,B|C]-[A,B|C])).
> difference_list_type_check_test(success,30,([1,A|B]-B)).
> difference_list_type_check_test(success,31,([1,A|B]-[A|B])).
> difference_list_type_check_test(success,32,([1,A|B]-[1,A|B])).
> difference_list_type_check_test(success,33,([A,1|B]-B)).
> difference_list_type_check_test(success,34,([A,1|B]-[1|B])).
> difference_list_type_check_test(success,35,([A,1|B]-[A,1|B])).
> 
> difference_list_type_check_test(fail ,01,([1|T1]-[1|T2])).
> difference_list_type_check_test(fail ,02,([1,2|T1]-[2|T2])).
> difference_list_type_check_test(fail ,03,([1,2,3|T1]-[3|T2])).
> difference_list_type_check_test(fail ,04,([1,2|T1]-[1,2|T2])).
> difference_list_type_check_test(fail ,05,([1,2,3|T1]-[2,3|T2])).
> difference_list_type_check_test(fail ,06,([1,2,3,4|T1]-[3,4|T2])).
> difference_list_type_check_test(fail ,07,([1,2,3|T1]-[1,2,3|T2])).
> difference_list_type_check_test(fail ,08,([1,2,3,4|T1]-[2,3,4|T2])).
> difference_list_type_check_test(fail ,09,([]-T2)).
> difference_list_type_check_test(fail ,10,([1]-T2)).
> difference_list_type_check_test(fail ,11,([1,2]-T2)).
> difference_list_type_check_test(fail ,12,([1,2,3]-T2)).
> difference_list_type_check_test(fail ,13,(T1-T2)).
> difference_list_type_check_test(fail ,14,([1|T1]-T2)).
> difference_list_type_check_test(fail ,15,([1,2|T1]-T2)).
> difference_list_type_check_test(fail ,16,([1,2,3|T1]-T2)).
> difference_list_type_check_test(fail ,17,([]-[1])).
> difference_list_type_check_test(fail ,18,([1]-[2])).
> difference_list_type_check_test(fail ,19,([1,2]-[3])).
> difference_list_type_check_test(fail ,20,([1]-[1,2])).
> difference_list_type_check_test(fail ,21,([1,2]-[2,3])).
> difference_list_type_check_test(fail ,22,([1,2,3]-[3,4])).
> difference_list_type_check_test(fail ,23,(a-b)).
> difference_list_type_check_test(fail ,24,(a-T2)).
> difference_list_type_check_test(fail ,25,((a)-T2)).
> difference_list_type_check_test(fail ,26,([[]]-T2)).
> difference_list_type_check_test(fail ,27,(a-a)).
> difference_list_type_check_test(fail ,28,([]-a)).
> difference_list_type_check_test(fail ,29,(a-[])).
> 
> test(is_type_success,[forall(difference_list_type_check_test(success,_,(L1-L2)))]) :-
> difference_list_type_check((L1-L2)).
> 
> test(is_type_fail,[fail,forall(difference_list_type_check_test(fail,_,(L1-L2)))]) :-
> difference_list_type_check((L1-L2)).
> 
> :- end_tests(difference_list).
> 
> ```

Example run.

```prolog
?- run_tests.
% PL-Unit: difference_list ................................................................ done
% All 64 tests passed
true.

```

* * *

If it was not for the help I received in this [post](https://swi-prolog.discourse.group/t/what-is-empty/2040) of better understating what is a difference list I would not have been able write this code.

---

_[View the full topic](https://swi-prolog.discourse.group/t/is-there-a-has-type-2-for-difference-list/2622)._
