2016-02-20 2 views
2

У меня есть список чисел в прологе. числа уже отсортированы. Я хочу проверить, что ни один из чисел не повторяется, а разные между любыми двумя числами больше одного. Как его проверить. Есть идеи. Спасибо.

?- check([1,3,4]). %expectation
false.
?- check([2,5,7,10]). %expectation
true.
проверить список чисел, отличающихся друг от друга в прологе

+2

Что вы пытаетесь? Поскольку вы имеете дело со отсортированными числами, вам нужно только проверить последовательные значения. Используйте тот факт, что список может быть записан как «[X1, X2 | T]», где «X1» и «X2» являются первыми двумя элементами в списке, а «T» - это остальная часть списка (хвост , также список). – lurker

+2

Ваша формулировка очень важна. Подумайте о описании **, что держит **. В идеале, полученное соотношение тогда будет использоваться во всех направлениях * и будет намного более общим, чем «проверка»: вы также сможете * генерировать * решения с ним. См. [Tag: clpfd] для описания отношений о целых числах. – mat

+1

Если я правильно вас понимаю ... вы не хотите проверять, что «между ** любым ** два числа больше одного». но вместо этого «разница между ** всеми ** соседними номерами больше одного». Правильно? – repeat

ответ

2

Я предполагаю, что список alreadeTry это ...

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

+3

Зачем использовать 'append/3' в этом контексте? Просто напишите 'check ([X1, X2 | T]): - ... .' вместо' check (L): - append ([], [X1, X2 | T], L), ....' – repeat

+2

Да, это правильно, мой список уже отсортирован. Также добавьте 'check ([]).' Для пустого списка. – Gamsh

2

Дай угадаю ...

  • Вы используете SWI-Prolog и
  • все номера, которые интересуют ваши check/1, являются целыми числами.

Если да, прочитайте дальше!


Используйте !

 
:- use_module (library(clpfd)). 

Как вы уже могли догадаться, есть миллиарды и миллиарды способов реализации предиката check/1. В этом ответе мы используем прямой вперед, непосредственно рекурсивный подход:

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

Примеры запросов:

 
?- 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` 

Вы заметили бинарный оператор (#<)/2 в приведенном выше определении check/1?

Это позволяет нам запускать общие запросы и получать логически обоснованные ответы. Рассматривать!

?- 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.