2
votes

I have a list of numbers in prolog. the numbers are already sorted.I want to check any of the numbers are not repeated and different between any two numbers is greater than one.How to check it. any idea. Thank you.

?- check([1,3,4]). %expectation
false.
?- check([2,5,7,10]). %expectation
true.

2
What have you tried? Since you're dealing with sorted numbers, you only need to check consecutive values. Use the fact that a list can be written as, [X1, X2|T] where X1 and X2 are the first two elements in the list, and T is the rest of the list (the tail, also a list).lurker
Your wording is very imperative. Think about describing what holds. Ideally, the resulting relation will then be usable in all directions, and will be much more general than a "check": You will also be able to generate solutions with it. See clpfd for describing relations about integers.mat
If I understand you correctly... you do not want to check that "different between any two numbers is greater than one". but instead "difference between all adjacent numbers is greater than one." Right?repeat
yes.any of the "difference between all adjacent numbers is greater than one." is the correct form how i will get it?Gamsh
Are the numbers you care for all integers?repeat

2 Answers

2
votes

I assume list alreadeTry it...

check([_]).
check(L):-append([],[X1,X2|T],L),X1+1<X2,check([X2|T]).

2
votes

Let me guess...

  • you are using SWI-Prolog, and
  • all numbers that your check/1 cares for are integers.

If so, read on!


Use !

:- use_module(library(clpfd)).

As you already might have guessed, there are a billions and billions of ways to implement the predicate check/1. In this answer we use a straight-forward, directly recursive approach:

check([]).
check([_]).
check([E0,E1|Es]) :-
   E0+1 #< E1,
   check([E1|Es]).

Sample queries:

?- check([1,3,4]).
false.

?- check([2,5,7,10]).
true ;                   % do not be bothered by the trailing `; false`
false.                   % `true ; false` is equivalent to `true`

Have you noticed the binary operator (#<)/2 in above definition of check/1?

It allows us to run general queries and get logically sound answers. Consider!

?- Xs = [1,A,B,C], check(Xs).
Xs = [1,A,B,C], A in 3..sup, A#=<B+ -2, B in 5..sup, B#=<C+ -2, C in 7..sup ;
false.