Создайте список и проверьте, увеличиваются ли значения - PullRequest
2 голосов
/ 16 мая 2019

В настоящее время я создаю список, в котором каждый элемент имеет значение, равное квадрату предыдущего элемента плюс значение Z. После генерации списка с использованием generate_list я хочу проверить, является ли он упорядоченным списком илине.Я реализовал заказанный, а затем в консоли, я пытаюсь сделать что-то вроде заказанного (generate_list (A, B, Z, [])., Который всегда возвращает false, даже когда я уверен, что это должно бытьправда. Я знаю, что этот подход не хорош в Прологе, но я не знаю, как это сделать ...

gen(0,0,_).
gen(N,F,Z) :- X is N-1,gen(X,A,Z),F is (A*A)+Z.

generate_list(A,B,Z,[]):- A>B.
generate_list(A,B,Z,[H|T]):-
    A =< B,
    gen(A,H,Z),
    AA is A + 1,
    generate_list(AA,B,Z,T).

ordered([]).
ordered([_]).
ordered([X,Y|Z]):-X=<Y,ordered([Y|Z]).

Ответы [ 3 ]

2 голосов
/ 16 мая 2019

Я не очень понимаю, почему вы указываете здесь функцию gen/3.Вы можете использовать аккумулятор и, таким образом, каждый раз обновлять аккумулятор, например:

generate_list(N, Z, L) :-
    generate_list(N, Z, 0, L).

generate_list(0, _, _, []).
generate_list(N, Z, A, [A|T]) :-
    N > 0,
    B is A*A + Z,
    N1 is N-1,
    generate_list(N1, Z, B, T).

Например, для Z это 1, мы получаем:

?- generate_list(5, 1, L).
L = [0, 1, 2, 5, 26] ;
false.

С предикатом ordered/1 в вашем вопросе мы видим, что этот список действительно упорядочен:

?- generate_list(5, 1, L), ordered(L).
L = [0, 1, 2, 5, 26] ;
false.

В то время как для Z = -1 это не так:

?- generate_list(5, -1, L).
L = [0, -1, 0, -1, 0] ;
false.

?- generate_list(5, -1, L), ordered(L).
false.
1 голос
/ 17 мая 2019

Чтобы расширить предыдущие ответы, в частности, от Willem Van Onsem, вы можете написать что-то вроде:

my_ord(P,L):- 
    call(P,L),
    ordered(L).

И тогда вы можете запросить ?- my_ord(generate_list(5, 1),L). Чтобы удалить точки выбора, вы можете использовать once/1 как для call/2, так и ordered/1, либо написать другой предикат, например my_ord_(P,L):- once(my_ord(P,L)), или поместить вырез !. Принимая во внимание ответ Виллема Ван Онсема, вам нужно добавить разрез после generate_list(0, _, _, []). В вашем заказанном / 1 вам нужен разрез после ordered([]) и ordered([_]).

1 голос
/ 17 мая 2019

Ваш ordered/1, вероятно, работает как есть. Но это оставляет точку выбора! Вы можете использовать once( sorted(L) ).

«Упорядоченный» чем-то похож на «отсортированный», не так ли?

Если вы можете иметь дубликаты в списке, используйте msort:

sorted(L) :- msort(L, L).

Если вы не разрешаете дублирование, используйте sort:

sorted_uniq(L) :- sort(L, L).

Ни один из них не оставляет за собой места выбора.

Это оставляет вам точку выбора, оставленную решением в другом ответе. Вы можете составить список, а затем заполнить его.

generate_list(N, Z, L) :-
    length(L, N),
    generate_list_1(L, Z, 0).

generate_list_1([], _, _).
generate_list_1([X|Xs], Z, X) :-
    X1 is X^2 + Z,
    X1 >= X, % Checks for order!
    generate_list_1(Xs, Z, X1).

Эта реализация дает вам только увеличивающиеся списки и не оставляет ненужных точек выбора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...