PROLOG - Split List - list

I'm using SWI-PROLOG and I'm having trouble splitting a list this way:
L = [a,b,c,d].
RESULT = [[a,b],[b,c],[c,d]].
I'm trying to approach this in a C/Java/etc. kind of way but I'm getting nowhere.
I'd appreciate any help in this simple matter, thank you!

One possible solution is this:
splitList([], []).
splitList([_], []).
splitList([A,B|T], R):- splitList([B|T], R1), R=[[A,B]|R1].
The idea is that you keep calling split until you get to the case of [X] (only one element in the list)
[a,b,c,d] ->
[b,c,d] ->
[c,d] ->
[d]
At this moment you get to the second case, and the backtracking starts
R1 = [] => R = [[c,d]|[]]
and so on.
Best way is to watch the trace.

Related

Haskell all possible ways to remove 1 element from the list

This is what I've written so far, but I've gotten a bit lost:
removeone :: [a] -> [[a]]
removeone [] = []
removeone (a:as) = [as] -- I'm lost here
This is the kind of output I'm looking for:
removeone [1,2,3] = [[2,3],[1,3],[1,2]]
removeone [1,2] = [[1],[2]]
What would be the best way to solve this problem? In Java I would just loop this and each time produce a new list that I would append to a pre-existing list. I am pretty lost in translating this into Haskell.
Let's look at a slightly longer example and figure out how to break it up:
> removeone [1,2,3,4]
[[2,3,4],[1,3,4],[1,2,4],[1,2,3]]
As you already guessed, you simply put as (the result of removing the first element from the input) on the front of some list, but what list is that?
removeone (a:as) = as : ...
Looking more closely, you can see that a == 1 is at the front of each of them. Let's factor that out to see how we might construct it:
[[1,3,4],[1,2,4],[1,2,3]] == [1:[3,4],1:[2,4],1:[2,3]]
== map (1:) [[3,4],[2,4],[2,3]]
The second argument should look familiar: it's what you should expect the result of removeone [2,3,4] to look like. And just like that, you have your recursive case:
removeone (a:as) = as : map (a:) (removeone as)
The idiomatic recursive solution is given by #сhepner. However, everyday Haskell is not about recursion, it's more about recursive patterns and precise formulation of a problem. If I have got it I would end up with following solution
import Data.List (inits, tails)
removeone :: [a] -> [[a]]
removeone lst = zipWith (++) (inits lst) (tail (tails lst))
It is more then 2× faster then explicit recursion and seems more like formulation of a problem. Using "dangerous" function tail is safe here because tails [] = [[]]. Trivial cases are held by zipWith, inits and tails.
If the resulting complementary lists are supposed to be nontrivially processed (say, they represent a view of each game personage in a group) consider Zippers and utilize their comonadic properties (it is really not as scaring as it sounds:)).

Creating sub-list from list in Prolog

I am having trouble understanding a concept in prolog.
I have a prolog list:
MyList = [item(dog,red), item(cat,black), item(rat,gray)]
and I am looking to create a list of just the colors i.e.
[red,black,gray]
Currently the solution I have tried is:
getlistcolors([item(_,C)|T], Result) :-
getlistcolors(T,Result),
append([C],Result,Result).
getlistcolors([],_).
I would like to be able to call the function:
?- getlistcolors(MyList, Result).
Result = [red,black,gray]
Any help is appreciated.
Thanks
Try with
getlistcolors([], []).
getlistcolors([item(_,C)|T], [C | Result]) :-
getlistcolors(T,Result).
You can't append the new find C color with
append([C],Result,Result)
because you're imposign that the second list and the appended list are equals.
You should use two different variables writing
getlistcolors([item(_,C)|T], Result) :-
getlistcolors(T,HeadC),
append([C],HeadC,Result).
but you can obtain the prepend-C effect simply translating C as head of the second argument
getlistcolors([item(_,C)|T], [C | Result]) :-
Second point wrong with your code: the terminal clause can't be written as
getlistcolors([], _).
or the second argument isn't unified with [] and the reasult become something like
[red,black,gray|_20]
where _20 is a variable that isn't unified.
Just to fix a problem in lurker comment:
when using setof/3 or bagof/3, you have to specify 'universal quantification' of each variable involved in the query, you're not interested in:
?- MyList = [item(dog,red), item(cat,black), item(rat,gray)],setof(Color, P^member(item(P, Color), MyList), ColorList).
MyList = [item(dog, red), item(cat, black), item(rat, gray)],
ColorList = [black, gray, red].
the missing quantification problem is better explained in the bagof section of inline documentation
A SWI-Prolog solution could make use of libraries yall and apply (both autoloaded, you don't have to worry about including them):
getlistcolors(List, Colors) :- maplist([E,C]>>(E = item(_,C)), List, Colors).
?- getlistcolors([item(dog,red), item(cat,black), item(rat,gray)],Cs).
Cs = [red, black, gray].

Prolog - Finding the longest increasing subsequence

I want to solve the following exercise in Prolog:
For a list of integers Zs, max_sequence(Zs,Xs) finds a longest increasing subsequence Xs.
Sample queries:
?- max_sequence([1,2,1,2,3,4,2,1,2,1],Xs).
Xs = [1,2,3,4]. % expected result
?- max_sequence([1,2,1,2,3,4,2,1,6,7,7,2,1,8],Xs).
Xs = [1,2,3,4,6,7,8]. % expected result
I can't understand why... but my code is wrong, the result is always false.
max_sequence(L,R) :-
cresc(L,[],R).
cresc([],[],[]).
cresc([H|T],C,[H|C]) :-
maxList(H,C),
\+ member(H,C),
cresc(T,C,C).
cresc([H|T],C,C) :-
member(H,C),
cresc(T,C,C).
cresc([H|T],C,C) :-
\+ maxList(H,C),
cresc(T,C,C).
maxList(_,[]).
maxList(N, [H|T]) :-
N>H,
maxList(N,T).
I would like to know if my approach to the problem is correct.
Thanks for any help!
TL;DR: Solve problems on a high-level: Think idiomatically; and don't reinvent the wheel :)
Use clpfd!
:- use_module(library(clpfd)).
We proceed by taking the following two steps:
We start by using the meta-predicate splitlistIfAdj/3 together with (#>=)/3:
?- splitlistIfAdj(#>=,[1,2,2,2,1,2,3,4,2,1,3,5,7,1],Zss).
Zss = [[1,2],[2],[2],[1,2,3,4],[2],[1,3,5,7],[1]].
We are only interested in sublists of maximum size. max_of_by/3 can exclude all other ones:
?- max_of_by(Xs,[[1,2],[2],[2],[1,2,3,4],[2],[1,3,5,7],[1]],length).
Xs = [1,2,3,4]
; Xs = [1,3,5,7].
That's it! Let's put it together and define list_longest_ascending_sublist/2:
list_longest_ascending_sublist(Xs,Zs) :-
splitlistAdjIf(#>=,Xs,Yss),
max_of_by(Zs,Yss,length).
Sample queries:
?- list_longest_ascending_sublist([1,2,2,2,1,2,3,4,2,1,3,5,7,1],Zs).
Zs = [1,2,3,4]
; Zs = [1,3,5,7].
?- list_longest_ascending_sublist([1,2,2,3,4,5,6,2,1,2,3,4,2,1,3,5,7,1],Zs).
Zs = [2,3,4,5,6].
I can't understand your approach at all, but using Trace command in swi-prolog you can see your program execution step by step to see where it fails. Try it and you will see what's wrong with your code.
Anyway this could be one possible solution: starting from the first element of the list you should simply collect a list until elements are increasing, keeping also the length of this sublist, this is the first candidate. Then start again collecting a new list and its length, and if is longer than the candidate, you switch them, and so on..
Here you can find the code: max_seqs , the first part.

Appending lists in SML

I'm trying to add an int list list with another int list list using the append function, but I can't get it to work the way I want.
Say that I want to append [[1,2,3,4,5]] with [6,7] so that I get [[1,2,3,4,5,6,7]].
Here's my attempt: [1,2,3,4,5]::[]#[6,7]::[], but it just gives me the list I want to append as a list of its own instead of the two lists combined into one, like this: [[1,2,3,4,5],[6,7]].
How can I re-write the operation to make it return [[1,2,3,4,5,6,7]]?
Your question is too unspecific. You are dealing with nested lists. Do you want to append the second list to every inner list of the nested list, or only the first one? Your example doesn't tell.
For the former:
fun appendAll xss ys = List.map (fn xs => xs # ys) xss
For the latter:
fun appendHd [] ys = raise Empty
| appendHd (xs::xss) ys = (xs # ys)::xss
However, both of these should rarely be needed, and I somehow feel that you are trying to solve the wrong problem if you end up there.

Value of the last element of a list

how to get the value of the last element of a List? I've noted that List.hd (or .Head) return an item, while List.tl (or .Tail) returns a List.
Is rev the List and get the hd the only way around? Thanks.
Try this function. It uses recursion, though it gets optimised to iteration anyway since it's tail recursion. In any case, it is most likely quicker than reversing the entire list (using List.rev).
let rec last = function
| hd :: [] -> hd
| hd :: tl -> last tl
| _ -> failwith "Empty list."
The answer of Pavel Minaev is definitely worth taking into account, however. Nonetheless, the algorithm you have requested may be useful in some rare cases, and is the most efficient way to go about the task.
In general, if you need to do this, you're doing something wrong. Since F# lists are single-linked, accessing the last element is costly - O(N), where N is size of list. Try to rewrite your algorithm so that you always access the first element, not the last (which is O(1)). If you cannot do so, chances are good that your choice of list for a data structure wasn't correct in the first place.
A quick & dirty way of doing it is by using List.reduce. Assuming the list is called ls,
let lastElement ls = List.reduce (fun _ i -> i) ls
As for efficiency, I agree with Pavel.
A more concise version based on Mitch's answer:
let lastItem = myList |> List.rev |> List.head
The myList list is sent to List.rev function. The result is then processed by List.head
Agreed, not so efficient to get the last element of list, or any other "enumerable" sequence. That said, this function already exists in the Seq module, Seq.last.
As a novice F# developer, I don't see what the harm is in doing the following
let mylist = [1;2;3;4;5]
let lastValue = mylist.[mylist.Length - 1]
Imperative in nature? Yes but no need for recursion.
The regular way to work with lists in F# is to use recursion. The first item in a list is the head (obviously) and the rest of the list is the tail (as oppose to the last item). So when a function recieves a list it processes the head and then recursively processes the rest of the list (the tail).
let reversedList = List.rev originalList
let tailItem = List.hd reversedList
I think you can just write
list.[0..list.Length-1]
You can call List.Head to get the first element of a list, such that the below expression evaluates to true:
let lst = [1;2;3;4;5]
List.head lst = 1
However, calling List.Tail will return every element in the list after the first element, such that the below expression is true:
let lst = [1;2;3;4;5]
List.tail lst = [2;3;4;5]
Like some other people have mentioned, there isn't an efficient way in F# to get the tail end of a list, basic lists just aren't built with that functionality in mind. If you really want to get the last element you're going to have to reverse your list first, and then take the new head (which was the previous tail).
let lst = [1;2;3;4;5]
(List.head (List.rev lst) ) = 5
Below code worked fine with me, I've an array of integers, want to start from the 5th item, then take it minus the item number
Sum of [Array(xi) - Array(xi-5)] where i start at 5
The code used is:
series |> Array.windowed 5
|> Array.fold (fun s x ->
(x |> Array.rev |> Array.head) - (x |> Array.head) + s) 0
|> float
It's a very old question, but just in case someone comes here:
with FSharp 5, you can do x.[^index] where index will start at the end of the array / list.
let a = [1;2;3;4;5;6;7;8;9]
a.[^0] is 9
a.[^1] is 8
etc