2015-01-31 3 views
2

У меня проблема со списками. Что мне нужно сделать, так это разбить один список [1,-2,3,-4] на два списка: [1,3] и [-2,-4]. Мой код выглядит следующим образом:Пролог, разбитый список на два списка

lists([],_,_). 
lists([X|Xs],Y,Z):- lists(Xs,Y,Z), X>0 -> append([X],Y,Y) ; append([X],Z,Z). 

, и я получаю

Y = [1|Y], 
Z = [-2|Z]. 

Что я делаю неправильно?

ответ

0

См образом:

domains 
    list=integer* 

predicates 
    split(list,list,list) 
clauses 
    split([],[],[]). 
    split([X|L],[X|L1],L2):- 
     X>= 0, 
     !,  
     split(L,L1,L2). 

    split([X|L],L1,[X|L2]):- 
     split(L,L1,L2). 

Выход:

Цель: сплит ([1,2, -3,4, -5,2], X, Y)
Решение: X = [1,2,4,2], Y = [- 3, -5]

Престол, если это помогает.

+0

Thats it, Thank you! – Paw

+0

Рад, что я мог помочь. –

1

Просто для разнообразия, это также может быть сделано с ВСО, который легко читать проблемы, как это:

split([], []) --> []. 
split([X|T], N) --> [X], { X >= 0 }, split(T, N). 
split(P, [X|T]) --> [X], { X < 0 }, split(P, T). 

split(L, A, B) :- 
    phrase(split(A, B), L). 

Как и в:

| ?- split([1,2,-4,3,-5], A, B). 

A = [1,2,3] 
B = [-4,-5] ? ; 

no 

Он также обеспечивает все возможные решения в обратном направлении:

| ?- split(L, [1,2,3], [-4,-5]). 

L = [1,2,3,-4,-5] ? ; 

L = [1,2,-4,3,-5] ? ; 

L = [1,2,-4,-5,3] ? ; 

L = [1,-4,2,3,-5] ? ; 

L = [1,-4,2,-5,3] ? ; 

L = [1,-4,-5,2,3] ? ; 

L = [-4,1,2,3,-5] ? ; 

L = [-4,1,2,-5,3] ? ; 

L = [-4,1,-5,2,3] ? ; 

L = [-4,-5,1,2,3] ? ; 

(2 ms) no 

Решение Gaurav также сделает это, если разрез будет удален и явный X < 0 проверяется в третьем предложении предиката split/3.

0

В вашем коде есть несколько исправлений. Если вам нравится компактный (читаемый) код, возможность является

lists([],[],[]). 
lists([X|Xs],Y,Z) :- 
    (X>0 -> (Y,Z)=([X|Ys],Zs) ; (Y,Z)=(Ys,[X|Zs])), lists(Xs,Ys,Zs). 

Но поскольку (SWI) Пролог предлагает библиотеки для обработки общих задач обработки списка, может быть столь же легко, как

lists(A,B,C) :- partition(<(0),A,B,C). 
1

Если используемые Система Prolog предлагает , вы можете сохранить . Хотите знать, как? Читайте дальше!

Мы принимаем второе определение lists/3, что @CapelliC написал в his answer в качестве отправной точки, и заменить partition/4 на tpartition/4 и (<)/2 по (#<)/3:

lists(A,B,C) :- tpartition(#<(0),A,B,C). 

Давайте рассмотрим пример запроса!

 
?- As = [0,1,2,-2,3,4,-4,5,6,7,0], lists(As,Bs,Cs). 
As = [0,1,2,-2,3,4,-4,5,6,7,0], 
Bs = [ 1,2, 3,4, 5,6,7 ], 
Cs = [0, -2, -4,  0]. 

Как мы используем монотонный код, мы получаем логически обоснованные ответы на более общие запросы:

?- As = [X,Y], lists(As,Bs,Cs). 
As = [X,Y], Bs = [X,Y], Cs = [ ], X in 1..sup, Y in 1..sup ; 
As = [X,Y], Bs = [X ], Cs = [ Y], X in 1..sup, Y in inf..0 ; 
As = [X,Y], Bs = [ Y], Cs = [X ], X in inf..0 , Y in 1..sup ; 
As = [X,Y], Bs = [ ], Cs = [X,Y], X in inf..0 , Y in inf..0 . 
0

Здесь у вас есть. Он разбивает список и не имеет значения, если он имеет нечетные или четные номера элементов.

div(L, A, B) :- 
    append(A, B, L), 
    length(A, N), 
    length(B, N). 

div(L, A, B) :- 
    append(A, B, L), 
    length(A, N), 
    N1 is N + 1, 
    length(B, N1). 

div(L, A, B) :- 
    append(A, B, L), 
    length(A, N), 
    N1 is N - 1, 
    length(B, N1). 
Смежные вопросы