user2585677
user2585677

Reputation: 149

How to define integer lists

I have a problem shown below.

Define integer list as follows:

  1. the empty list is an integer list
  2. if L is an integer list and N is an integer then [N | L] is an integer list
  3. if L1 and L2 are integer lists, so is [L1 | L2].

Write a prolog program integer_list(L) that is satisfied if only if L is an integer list.

My program cannot implement the 3rd requirement. Can someone point out to me the mistake?

int_list([]):-!.
int_list(L):-
   is_list(L),
   L=[X|Y],
   check(L).
int_list(L):-
   L=[L1|L2],
   is_list(L1),
   is_list(L2),
   check(L1),
   check(L2).


check([]):-!.
check([X|Y]):-
  integer(X),
  check(Y).

Upvotes: 2

Views: 894

Answers (2)

Nicholas Carey
Nicholas Carey

Reputation: 74297

Try something like:

integer_list( X      ) :-   % an unbound variable is NOT an integer list.
  var(X) ,                  %
  ! ,                       %
  fail.                     %
integer_list( []     ) .    % The empty list is an integer list.
integer_list( [X|Xs] ) :-   % A non-empty list is an integer list if:
  integer(X) ,              % - its head is an integer, and
  integer_list(Xs) .        % - its tail is an integer list.
integer_list( [X|Xs] ) :-   % A non-empty list is an integer list if:
  integer_list(X) ,         % - its head is an integer list, and
  integer_list(Xs)          % - its tail is an integer list.
  .                         % Easy!

Upvotes: 3

CapelliC
CapelliC

Reputation: 60034

I think you can do more simply, extending check to accept lists of integers:

int_list([]).
int_list([X|Xs]) :- check(X), int_list(Xs).

check([X|Xs]) :- check(X), int_list(Xs).
check(X) :- integer(X).

note: try to avoid cuts when not necessary (i.e. to commit to a specific choice). The code will be easier to understand, and equally efficient, if you let Prolog pattern matching discriminate branches.

Upvotes: 3

Related Questions