Delete Last 3 elements of List L to make List L1 in Prolog
How do i write a goal that deletes the last three elements from a list L producing another list 开发者_Go百科L1?
Also, how would I write multiple goals to delete the first three elements and the last three elements from a list L producing L2?
Prolog it's a bit different from other languages, but it also has a libray (standard ISO) that's worth to learn:
delete_last_3(L, L1) :-
append(L1, [_,_,_], L).
Now the other request come easy:
delete_first_and_last_3(L, L2) :-
append([_,_,_], LT, L), delete_last_3(LT, L2).
Test:
?- delete_last_3([1,2,3,4,5,6,7],X).
X = [1, 2, 3, 4] .
?- delete_first_and_last_3([1,2,3,4,5,6,7,8,9],L).
L = [4, 5, 6] .
You might want to try something like this:
without_last_three([_,_,_], []).
without_last_three([Head|Tail], [Head|NTail]):-
without_last_three(Tail, NTail).
without_three_sides([_,_,_|L], L2):-
without_last_three(L, L2).
The first predicate will return a list without the last three elements, and fail in case there are less than three elements.
The second predicate will return a list without the first and last three elements, and fail in case there are less than six elements.
Step one of logic programming, start with the base cases. What do you want to happen when there are fewer than three elements? I guess you want an empty list?
without_last_three([], []).
without_last_three([_], []).
without_last_three([_,_], []).
without_last_three([_,_,_], []).
Now, for a list with more than three elements, you want to keep the first element, and remove three from the remaining elements. You might first try to write:
without_last_three([A|L], [A|M]) :- without_last_three(L, M). !!wrong
but this will cause incorrect results due to back-tracking. The simplest way to fix that is to verify that L has more than three elements:
without_last_three([A,B,C,D|L], [A|M]) :- without_last_three([B,C,D|L], M).
But a more elegant solution would be to use Prolog's cut operator:
without_last_three([A|L], [A|M]) :- !, without_last_three(L, M).
To implement without_first_three, without getting bored, you could simply reverse the list, remove the last three, and flip it back again:
without_first_three(I, O) :- reverse(I, A), without_last_three(A, B), reverse(B, O).
or you could just write down some really simple rules:
without_first_three([], []).
without_first_three([_], []).
without_first_three([_,_], []).
without_first_three([_,_,_|L], L).
(Thinking about it, maybe it would be nicer to implement without_last_three in terms of without_first_three, not the other way around)!
精彩评论