Checking if unification between two elements is True or False - list

So my problem is this i have this predicate equal(X,Y) which says basically that X is equal to Y and unifies them if they are, as long as they have the same length, but what i want is the predicate to give true or false but instead, it gives me the unifications.
If somebody could help i would appreciate it a lot.
My output:
?- equal([[d, r, a, m, a],[a, m, e, n, o]],[[P11, P21, P31, P41, P51], [a, P23, P33, P43, P53]]).P11 = d,
P21 = r,
P31 = P51, P51 = a,
P41 = P23, P23 = m,
P33 = e,
P43 = n,
P53 = o .
?- equal([[a, m, e, n, o]],[[P11, P21, P31, P41, P51], [a, P23, P33, P43, P53]]).
false.
As you can see the substituitions are fine, like i want those substituitions to happen, but the i dont want them as the output, what i want is whether this is True or False which in this case is True.
Correct output:
?- equal([[d, r, a, m, a],[a, m, e, n, o]],[[P11, P21, P31, P41, P51], [a, P23, P33, P43, P53]]).P11 = d,
true.
?- equal([[a, m, e, n, o]],[[P11, P21, P31, P41, P51], [a, P23, P33, P43, P53]]).
false.
Program:
isSubset([],_).
isSubset([H|T],Y):-
member(H,Y),
select(H,Y,Z),
isSubset(T,Z).
equal(X,Y):-
isSubset(X,Y),
isSubset(Y,X).

You can approach this using Lambda expressions (e.g. with the yall library of SWI-Prolog).
Prolog will yield bindings only for those variables placed within the { } before the query:
?- {P11, P21}/equal([[d, r, a, m, a],[a, m, e, n, o]],[[P11, P21, P31, P41, P51], [a, P23, P33, P43, P53]]).
P11 = d,
P21 = r .
But note that you can also leave the brackets empty and yield no bindings:
?- {}/equal([[d, r, a, m, a],[a, m, e, n, o]],[[P11, P21, P31, P41, P51], [a, P23, P33, P43, P53]]).
true .
This seems to be essentially the functionality you want. You could throw it into a helper rule to make things easier. The following will give you true for each valid relation for equal/2 in the facts:
isEqual(X, Y) :-
{}/equal(X, Y).
If you want to know only if one or more valid relations for equal/2 exists in the facts, then you could add a cut !:
isEqual(X, Y) :-
{}/equal(X, Y),
!.
Output for your query is thus:
?- isEqual([[d, r, a, m, a],[a, m, e, n, o]],[[P11, P21, P31, P41, P51], [a, P23, P33, P43, P53]]).
true.

Related

Splitting a list into two sublists with one having a predefined length

I'm new to Prolog and I have this code. I would like it to split a list into two lists or sublists where the first sublist/ list is of a predefined length and the other one contains the rest of the elements. Here's the code.
`
list_length([],0).
list_length([_|T],N):- list_length(T, N1), N is N1 + 1.
div(L, A, B, N) :-
append(A, B, L),
length(A, N),
length(B, N).
div(L, A, B, N) :-
append(A, B, L),
length(A, N),
N1 is N + 1,
length(B, N1).
div(L, A, B, N) :-
append(A, B, L),
length(A, N),
N1 is N - 1,
length(B, N1).
``
When I run my above code, it returns an error saying:
ERROR: Unknown procedure: (div)/4
ERROR: However, there are definitions for:
ERROR: (div)/3
false.
I would like the input to be this:
`?- div([44,55,23,86,49,94,30,77], L1, L2, 6).
L1 = [44,55,23,86,49,94]
L2 = [30,77]
Help me understand what I am doing wrong.
Help me understand what I am doing wrong.
You should be using length/2 and append/3, one after the other, like this:
div(L, A, B, N) :-
append(A, B, L),
length(A, N).
This is all.
Do not define your own length/2.
But you have not shown how you compile and evaluate your code. For example, I get:
?- [user].
|: div(L, A, B, N) :- append(A, B, L), length(A, N).
|: ^D% user://1 compiled 0.01 sec, 1 clauses
true.
?- div([a,b,c,d], A, B, 2).
A = [a, b],
B = [c, d] ;
false.
?- div([a,b,c,d], [X,Y], B, N).
X = a,
Y = b,
B = [c, d],
N = 2.
?- div([a,b,c,d], A, [X,Y,Z], N).
A = [a],
X = b,
Y = c,
Z = d,
N = 1 ;
false.
?- div([a,b], A, B, N).
A = [],
B = [a, b],
N = 0 ;
A = [a],
B = [b],
N = 1 ;
A = [a, b],
B = [],
N = 2 ;
false.
?- div(L, A, B, N).
L = B,
A = [],
N = 0 ;
L = [_A|B],
A = [_A],
N = 1 ;
L = [_A, _B|B],
A = [_A, _B],
N = 2 .
Since I made that mistake already, it is worth asking: Can you switch the order of append and length in the definition? What happens if you do?

Checking all the words in list that unify with list of variables

So i have predicate called palavras_possiveis_esp(Leters,Spaces,Space,Words_pos), Leters which is a list of words like [[d,a,y],[n,i,g,h,t],[s,u,n],[m,o,o,n]], Spaces is list of lists like [[P11,P12,P13],[P11,P21,P31,P41],[P13,P23,P33]], a Space is list with variables like this [P11,P12,P13] and Words_pos is all the words that can be unified with a certain Space.
Firstly to do this, i did this predicate espacos_pal_uni(Spaces,Leters) and the purpose of this predicate is to unify all the Esps with any of the words in Ltrs
Example:
?- espacos_pal_uni([[d, P21, P31, P41, P51],[a, P23, P33, P43, P53]],[[a,m,e,n,o],[a,t,o],[d,a,o],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]]).P21 = r,
P31 = P51, P51 = a,
P41 = P23, P23 = m,
P33 = e,
P43 = n,
P53 = o.
So as you can see from the example the Space [d, P21, P31, P41, P51] was unified with the word drama and the Space [a, P23, P33, P43, P53] was unified with the word ameno.
Secondly, i created this predicate palavra_possivel_esp(Word, Space, Spaces, Leters) and the purpose of this predicate is unify a Space with Word, if they are, then they unify Esps that have common variables with Esp with any of the words in Ltrs
Example:
?- Letras = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,i,a],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Espacos = [[P11, P12, P13], [P15, P16, P17, P18],
[P23, P24, P25],
[P35, a, P37],
[P41, P42, P43, P44, P45],
[P11, P21, P31, P41, P51],
[P13, P23, P33, P43, P53],
[P15, P25, P35, P45],
[P17, P27, P37]],
palavra_possivel_esp([d,i,a], [P11,P12,P13], Espacos, Letras).
P11 = P35, P35 = d,
P12 = i,
P13 = P31, P31 = P51, P51 = a,
P21 = r,
P23 = P41, P41 = m,
P33 = e,
P37 = P53, P53 = o,
P43 = n,
Letras = [[a, m, e, n, o], [a, t, o], [d, a, o], [d, i, a], [d, r, a, m|...], [m, a, e], [m, a|...], [s|...], [...|...]],
Espacos = [[d, i, a], [P15, P16, P17, P18], [m, P24, P25], [d, a, o], [m, P42, n, P44|...], [d, r, a|...], [a, m|...], [P15|...], [...|...]].
?- Leters = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,i,a],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Spaces = [[P11, P12, P13], [P15, P16, P17, P18],
[P23, P24, P25],
[P35, a, P37],
[P41, P42, P43, P44, P45],
[P11, P21, P31, P41, P51],
[P13, P23, P33, P43, P53],
[P15, P25, P35, P45],
[P17, P27, P37]],
palavra_possivel_esp([d,a,o], [P11,P12,P13], Spaces, Leters).
1) So whats happening here is the predicate unifies the word [d,i,a] with [P11,P12,P13], and then it checks the Spaces that have variables in common with that Space, which are [[P11, P21, P31, P41, P51], [P13, P23, P33, P43, P53]], then it will se if there are any word in Leters that unifies with [[d, P21, P31, P41, P51], [a, P23, P33, P43, P53]] which are the words ameno and drama.
2) As for the word dao the predicate unifies the word [d,a,o] with [P11,P12,P13], and then it checks the Esps that have variables in common with that Sapce, which are [[P11, P21, P31, P41, P51], [P13, P23, P33, P43, P53]], then it will se if there are any word in Leters that in unifies with [[d, P21, P31, P41, P51], [o, P23, P33, P43, P53]], the first word is unifiable with drama but since there's no word starting with o, then it returns False.
Thirdly, i created a predicate palavras_possiveis_esp(Leters, Spaces Space, Words_Pos), which Words_Pos is a list of all words unifiable with a certain space.
Example:
?- Letras = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,i,a],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Espacos = [[P11, P12, P13], [P15, P16, P17, P18],
[P23, P24, P25],
[P35, a, P37],
[P41, P42, P43, P44, P45],
[P11, P21, P31, P41, P51],
[P13, P23, P33, P43, P53],
[P15, P25, P35, P45],
[P17, P27, P37]],
palavras_possiveis_esp(Letras, Espacos,[P11,P12, P13], Pals_Possiveis).
P11 = P35, P35 = d,
P12 = i,
P13 = P31, P31 = P51, P51 = a,
P21 = r,
P23 = P41, P41 = m,
P33 = e,
P37 = P53, P53 = o,
P43 = n,
Letras = [[a, m, e, n, o], [a, t, o], [d, a, o], [d, i, a], [d, r, a, m|...], [m, a, e], [m, a|...], [s|...], [...|...]],
Espacos = [[d, i, a], [P15, P16, P17, P18], [m, P24, P25], [d, a, o], [m, P42, n, P44|...], [d, r, a|...], [a, m|...], [P15|...], [...|...]],
Pals_Possiveis = [[d, i, a]].
The problem here is that if there is more than 1 word that unifies with a Space, the predicate returns a list with the 1st word instead of the list with all the words.
The problem i think is that when it searches for the 1st word and unifies it with the space, since the space will no longer be a list of variables then it will always be different than the rest of the words and it will return the 1st word and i cant see how i fix this.
I think the major problem is in the espacos_pal_uni predicate.
Program:
espacos_pal_uni([],_) :- true.
espacos_pal_uni([E|RE],LP) :- member(E,LP),
espacos_pal_uni(RE,LP).
palavra_possivel_esp(Pal, Esp, Esps, Letras) :-
length(Pal,C1),
length(Esp,C2),
C1 == C2,
Pal = Esp,
espacos_com_posicoes_comuns(Esps,Esp,NEsps),
espacos_pal_uni(NEsps,Letras),!.
npalavra_possivel_esp(P, Esp, Esps, Ltrs) :- \+ palavra_possivel_esp(P, Esp, Esps, Ltrs).
palavras_possiveis_esp(Ltrs,Esps,Esp,Pals) :-
palavras_possiveis_esp(Ltrs,Esps,Esp,Pals,Ltrs,[]).
palavras_possiveis_esp(_,_,_,AC,[],AC) :- !.
palavras_possiveis_esp(Ltrs,Esps,Esp,Pals,[P|R],AC) :-
palavra_possivel_esp(P, Esp, Esps, Ltrs),
append(AC,[P],NAC),
palavras_possiveis_esp(Ltrs,Esps,Esp,Pals,R,NAC).
palavras_possiveis_esp(Ltrs,Esps,Esp,Pals,[P|R],AC) :-
npalavra_possivel_esp(P, Esp, Esps, Ltrs),
This looks like it's partly a duplicate of Checking if a list of variables is unifiable with a list of lists containing letters. See there for an answer for checking whether a word unifies with a "space".
The problem here is that if there is more than 1 word that unifies with a Space, the predicate returns a list with the 1st word instead of the list with all the words.
To find a list of all words that unify with a "space", use a filter predicate instead of member/2.

checking if there a list of lists can unify with another list of lists

So i have two predicates the 1st is palavra_uni(Word,Var) in which Word is list of words like [[d,a,y],[n,i,g,h,t]] for example and Var is list that contains vars or constants like [P1,P2,P3] or [d,P2,P3].
The purpose of the first predicate is to return true if any of the any list of words is unifiable with Var.
Example:
?- palavras_uni([[a, m, e, n, o], [a, t, o], [d, a, o], [d, i, a]],[P12,P13,P14]).
true.
?- palavras_uni([[d,a,y], [n,i,g,h,t]],[P12,a,P14]).
true.
?- palavras_uni([[d,a,y], [n,i,g,h,t]],[P12,P13]).
false.
Well the problem is that this predicate shows the unified variables instead of giving true.
Example:
?- palavras_uni([[a, m, e, n, o], [a, t, o], [d, a, o], [d, i, a]],[P12,P13,P14]).
P12 = a,
P13 = t,
P14 = o.
?- palavras_uni([[d,a,y], [n,i,g,h,t]],[P12,a,P14]).
P12 = d,
P14 = y.
?- palavras_uni([[d,a,y], [n,i,g,h,t]],[P12,P13]).
false.
As for my 2nd problem i have a predicate called espacos_uni(LS,LP) in which Ls is a list of lits containing variables for example [[P11, P21, P31, P41, P51], [P13, P23, P33, P43, P53]] and LP is list of list containing words just like before, for example [[d,a,y],[n,i,g,h,t]].
The purpose of this predicate is to return true if any of the words is unifiable with any of the Vars
Example:
?- espacos_uni([[P11, P21, P31, P41, P51], [a, P23, P33, P43, P53]],[[a, m, e, n, o],[a, t, o], [d, a, o],[d, r, a, m, a], [m, a, e], [m, a, n, d, e], [s, e, d, e], [s, o, a, r]]).
true.
But instead of giving true this is giving false all the time and i cant understand why.
Program:
palavra_uni([P|_],E) :- P = E,!.
palavra_uni([P|R],E) :- P \= E,
palavra_uni(R,E).
espacos_uni([P|R],LP) :- palavra_uni(LP,P),
espacos_uni(R,LP).
espacos_uni([P|R],LP) :- \+ palavra_uni(LP,P),
espacos_uni(R,LP).
First part of your question:
That is the behavior of Prolog. If Prolog can prove your query, it will print out the satisfying assignment of the free variables in your query. So if you see variables being printed out, this is equivalent to true.
You can suppress the printing of variables by using _ (anonymous variable):
?- palavras_uni([[a, m, e, n, o], [a, t, o], [d, a, o], [d, i, a]],[_,_,_]).
true.
As soon as you give the variables a name, you are signaling to Prolog that you are interested in their values.
Second part of your question:
You have two rules for espacos_uni.
The first says that espacos_uni is true if the first entry in the variable list unifies with any entry of the word list and the remaining part of the variable list again satisfies espacos_uni.
The second says that espacos_uni is true if the first entry in the variable list does not unify with any entry in the word list and the remaining part of the variable list satisfies espacos_uni.
The second rule is fine. The problem is with the first rule: It will successfully find the matches, but then always go on looking for further matches, which eventually fails when the list becomes empty. You can fix this by removing the recursion in the first rule:
espacos_uni([P|_],LP) :- palavra_uni(LP,P).

How to swap three by three elements in a prolog list?

I'm doing an exercise in Prolog and I'm stuck.
I need to swap three adjacent items in a list with another three elements.
That is:
| ?- swap([c,g,g,a,t,t,g,c,a,a], X).
X = [a,t,t,c,g,g,g,c,a,a]
X = [g,c,a,a,t,t,c,g,g,a]
X = [c,g,g,g,c,a,a,t,t,a]
X = [c,a,a,a,t,t,g,c,g,g]
.
.
.
This is what I have so far:
swap([H1, H2, H3, H4, H5, H6|T1], X) :-
X = [H4, H5, H6, H1, H2, H3|T1];
swap([H2, H3, H4, H5, H6|T1], X);
swap([H1, H2, H3, H4, H5|T1], X).
And the output for this is:
| ?- swap([c,g,g,a,t,t,g,c,a,a], X).
X = [a, t, t, c, g, g, g, c, a, a] ;
X = [t, t, g, g, g, a, c, a, a] ;
X = [t, g, c, g, a, t, a, a] ;
X = [g, c, a, a, t, t, a] ;
X = [c, a, a, t, t, g] ;
X = [c, a, a, a, t, t] ;
X = [g, c, a, g, a, t, a] ;
X = [c, a, a, a, t, g] ;
X = [c, a, a, g, a, t] ;
X = [t, g, c, g, g, a, a, a] ;
X = [g, c, a, g, a, t, a] ;
X = [c, a, a, a, t, g] ;
X = [c, a, a, g, a, t] ;
X = [g, c, a, g, g, a, a] ;
X = [c, a, a, g, a, g] ;
X = [c, a, a, g, g, a] ;
X = [t, t, g, c, g, g, c, a, a] ;
X = [t, g, c, g, g, t, a, a] ;
X = [g, c, a, g, t, t, a] ;
X = [c, a, a, t, t, g] ;
X = [c, a, a, g, t, t] ;
X = [g, c, a, g, g, t, a] ;
X = [c, a, a, g, t, g] ;
X = [c, a, a, g, g, t] ;
X = [t, g, c, c, g, g, a, a] ;
X = [g, c, a, g, g, t, a] ;
X = [c, a, a, g, t, g] ;
X = [c, a, a, g, g, t] ;
X = [g, c, a, c, g, g, a] ;
X = [c, a, a, g, g, g] ;
X = [c, a, a, c, g, g] ;
false.
The only problem that I have is that with every recursion I lose some part of the list and I don't know how to put it back.
It seems you are interested in describing RNA-sequences. Triples, that sounds much like anticodons. To make those sequences more readable, use:
:- set_prolog_flag(double_quotes, chars).
which permits you to write "attac" in place of [a,t,t,a,c]. See this how to get also compact answers.
Now for the swap. The easiest way is to first sketch what you want:
... Triple1 ... Triple2 ... is the OldSequence
... Triple2 ... Triple1 ... is the NewSequence
Where the ... are the same for both sequences. All of this can be readily translated using DCGs.
tripleswap(OldSequence, NewSequence) :-
dif(T1,T2),
phrase( ( seq(A), triple(T1), seq(B), triple(T2), seq(C) ), OldSequence),
phrase( ( seq(A), triple(T2), seq(B), triple(T1), seq(C) ), NewSequence).
seq([]) --> [].
seq([B|Bs]) --> [B], seq(Bs).
triple([A,B,C]) --> [A,B,C].
Whenever you distrust a DCG-definition, just try it out with phrase/2. Like
?- phrase(triple(T1), Bs).
T1 = Bs, Bs = [_A,_B,_C].
The non-terminal triple//1 describes a sequence of 3 elements (presumably nucleotides).
seq//1 is an arbitrarily long sequence.
There are solutions with better termination conditions, but they are less readable and often require certain assumptions that are difficult to maintain in the general case. Here is such a simple improvement:
samelength([], []).
samelength([_|Xs], [_|Ys]) :-
samelength(Xs, Ys).
and add samelength(OldSequence, NewSeqence) as the first goal. Now, tripleswap/2 terminates iff samelength/2 terminates. So one of the arguments should be a list of fixed length.
Also note that I think that "cccccc" has no swap. That's why I added dif(T1,T2).
?- tripleswap("cggattgcaa", Bs).
Bs = "attcgggcaa"
; Bs = "ttgacggcaa"
; Bs = "tgcatcggaa"
; Bs = "gcaattcgga"
; Bs = "caaattgcgg"
; Bs = "cttgggacaa"
; Bs = "ctgctggaaa"
; Bs = "cgcattggaa"
; Bs = "ccaattggga"
; Bs = "cgtgcgataa"
; Bs = "cggcatgata"
; Bs = "cgcaatggat"
; Bs = "cgggcaatta"
; Bs = "cggcaagatt"
; Bs = "cggacaattg"
; false.
BTW, dcgs are used in Molecular Biology since the 1980s. Start with
David B. Searls, Investigating the Linguistics of DNA with Definite Clause Grammars, NACLP 1989
and other work by the same author as well as Ross Overbeek around that time. All of this happened in the dawn of the Human Genome Project.
Basically this can be split into two subproblems:
first take a sequence of three elements; and
take another sequence of three elements and produce a list where we swapped these.
We can thus implement the two problems as follows:
swap(L, X) :-
swap1(L, S1, S2, T, X, Q),
swap2(T, S1, S2, Q).
where L is the list where we need to perform the swaps, X the list that is unified with the results, S1 and S2 the sequences that we select to swap, T the remaining elements after the first selection, and Q the part after the second sequence of the list to swap.
The first swap1 can thus be implemented as:
swap1([A1, A2, A3|T], [A1, A2, A3], [B1, B2, B3], T, [B1, B2, B3|Q], Q).
swap1([A1|T], A, B, R, [A1|Rest], S) :-
swap1(T, A, B, R, Rest, S).
For the given sample list, this will thus yield:
?- swap1([c,g,g,a,t,t,g,c,a,a], A, [B1, B2, B3], T, X, R).
A = [c, g, g],
T = [a, t, t, g, c, a, a],
X = [B1, B2, B3|R] ;
A = [g, g, a],
T = [t, t, g, c, a, a],
X = [c, B1, B2, B3|R] ;
A = [g, a, t],
T = [t, g, c, a, a],
X = [c, g, B1, B2, B3|R] ;
A = [a, t, t],
T = [g, c, a, a],
X = [c, g, g, B1, B2, B3|R] ;
A = [t, t, g],
T = [c, a, a],
X = [c, g, g, a, B1, B2, B3|R] ;
A = [t, g, c],
T = [a, a],
X = [c, g, g, a, t, B1, B2, B3|R] ;
A = [g, c, a],
T = [a],
X = [c, g, g, a, t, t, B1, B2, B3|...] ;
A = [c, a, a],
T = [],
X = [c, g, g, a, t, t, g, B1, B2|...] ;
false.
Here it thus proposes eight ways to pick three adjacent sequences that can be used to swap.
Then the second swap need to find three adjacent elements in the remaining lists to swap, and put the ones that have been picked by swap1/6 at the places where it picks elements from, like:
swap2([B1,B2,B3|R], [A1,A2,A3], [B1, B2, B3], [A1,A2,A3|R]).
swap2([B1|R], As, Bs, [B1|T]) :-
swap2(R, As, Bs, T).
For the given sample data, this thus gives us:
?- swap([c,g,g,a,t,t,g,c,a,a], X).
X = [a, t, t, c, g, g, g, c, a, a] ;
X = [t, t, g, a, c, g, g, c, a, a] ;
X = [t, g, c, a, t, c, g, g, a, a] ;
X = [g, c, a, a, t, t, c, g, g, a] ;
X = [c, a, a, a, t, t, g, c, g, g] ;
X = [c, t, t, g, g, g, a, c, a, a] ;
X = [c, t, g, c, t, g, g, a, a, a] ;
X = [c, g, c, a, t, t, g, g, a, a] ;
X = [c, c, a, a, t, t, g, g, g, a] ;
X = [c, g, t, g, c, g, a, t, a, a] ;
X = [c, g, g, c, a, t, g, a, t, a] ;
X = [c, g, c, a, a, t, g, g, a, t] ;
X = [c, g, g, g, c, a, a, t, t, a] ;
X = [c, g, g, c, a, a, g, a, t, t] ;
X = [c, g, g, a, c, a, a, t, t, g] ;
false.
Here the places that are swapped are written in boldface.
I think permutation/2 will help:
swap(Es,Sw) :- triples(Es,Ts),permutation(Ts,Sw0),append(Sw0,Sw).
triples([A,B,C|Es],[[A,B,C]|Ts]) :- !, triples(Es,Ts).
triples([],[]) :- !.
triples(R,[R]).
yields
?- swap([c,g,g, a,t,t, g,c,a], X).
X = [c, g, g, a, t, t, g, c, a] ;
X = [c, g, g, g, c, a, a, t, t] ;
X = [a, t, t, c, g, g, g, c, a] ;
X = [a, t, t, g, c, a, c, g, g] ;
X = [g, c, a, c, g, g, a, t, t] ;
X = [g, c, a, a, t, t, c, g, g] ;
false.
note: triples/2 allows for not triple data in tail, but you can drop this (maybe unwanted) feature just deleting the last clause:
triples(R,[R]). % drop this
Then the cuts become useless, just drop drop them:
triples([],[]). % just for style in this case, move to first clause
triples([A,B,C|Es],[[A,B,C]|Ts]) :- triples(Es,Ts).

Splitting a list with odd length into two lists equal in length in Prolog

I am writing a predicate in Prolog to divide a list into two equal in length lists. For example :
spliting([a, b, c, d, e], L1, L2)
produces:
L1 = [a, b, c], L2 = [d, e].
My code:
parimpar(L, A, B) :-
split(L, L, A, B).
split(B, [], [], B).
split([H|T], [_, _|T1], [H | T2], B) :-
split(T, T1, T2, B).
But it is working only the list to split is of even length.
How can I resolve that?