Related
i am a beginner in ocaml and I am stuck in my project.
I would like to count the number of elements of a list contained in a list.
Then test if the list contains odd or even lists.
let listoflists = [[1;2] ; [3;4;5;6] ; [7;8;9]]
output
l1 = even
l2 = even
l3 = odd
The problem is that :
List.tl listoflists
Gives the length of the rest of the list
so 2
-> how can I calculate the length of the lists one by one ?
-> Or how could I get the lists and put them one by one in a variable ?
for the odd/even function, I have already done it !
Tell me if I'm not clear
and thank you for your help .
Unfortunately it's not really possible to help you very much because your question is unclear. Since this is obviously a homework problem I'll just make a few comments.
Since you talk about putting values in variables you seem to have some programming experience. But you should know that OCaml code tends to work with immutable variables and values, which means you have to look at things differently. You can have variables, but they will usually be represented as function parameters (which indeed take different values at different times).
If you have no experience at all with OCaml it is probably worth working through a tutorial. The OCaml.org website recommends the first 6 chapters of the OCaml manual here. In the long run this will probably get you up to speed faster than asking questions here.
You ask how to do a calculation on each list in a list of lists. But you don't say what the answer is supposed to look like. If you want separate answers, one for each sublist, the function to use is List.map. If instead you want one cumulative answer calculated from all the sublists, you want a fold function (like List.fold_left).
You say that List.tl calculates the length of a list, or at least that's what you seem to be saying. But of course that's not the case, List.tl returns all but the first element of a list. The length of a list is calculated by List.length.
If you give a clearer definition of your problem and particularly the desired output you will get better help here.
Use List.iter f xs to apply function f to each element of the list xs.
Use List.length to compute the length of each list.
Even numbers are integrally divisible by two, so if you divide an even number by two the remainder will be zero. Use the mod operator to get the remainder of the division. Alternatively, you can rely on the fact that in the binary representation the odd numbers always end with 1 so you can use land (logical and) to test the least significant bit.
If you need to refer to the position of the list element, use List.iteri f xs. The List.iteri function will apply f to two arguments, the first will be the position of the element (starting from 0) and the second will be the element itself.
I'm trying to test if a list of brackets is valid. My code:
checkbrackets([]).
checkbrackets(['('|T]):-
T = [')'|List],
checkbrackets(List).
checkbrackets(['('|T]):-
T = ['('|List],
append(Rest,[')'],T),
checkbrackets(Rest).
My code works for ['(', '(', ')', '(', '(', ')', ')', ')']
but it fails for ['(', '(', ')', ')', '(', ')'].
What am I doing wrong? Is it possible to write such a test without additional arguments like counters?
your append(Rest, [')'], T) will parse until the end of the list, but it is not said that the opening bracket will eventually match with the last closing bracket, for example ()() does not.
That being said, I think you make things overcomplicated. Instead of obtaining all sorts of sublists, you can use a single scan here: you use an accumulator that you initialize with 0, and the accumulator should eventually end with 0 and never be less than zero, so:
checkbrackets(B) :-
checkbrackets(B, 0).
checkbrackets([], 0). %% ← at the end, zero
checkbrackets([')'|T], N) :-
N > 0, %% ← always greater than or equal to zero.
N1 is N-1,
checkbrackets(T, N1).
checkbrackets(['('|T], N) :-
N1 is N+1,
checkbrackets(T, N1).
For the sake of completeness, here is a solution without additional arguments.
checkbrackets([]).
checkbrackets(['('|Rest]):-
append(Sub1,[')'|Sub2],Rest),
checkbrackets(Sub1),
checkbrackets(Sub2).
It simply follows the definition of "properly parenthesized" expression. Either it is empty, or it starts with a (, followed by a properly parenthesized subexpression (Sub1), followed by ), followed by another properly parenthesized subexpression (Sub2).
However, it is fairly inefficient as compared to the direct solution with one extra argument presented by Willem Van Onsem. The main issue is that the append/3 call needs to non-deterministically "guess" the position of the matching closing parenthesis and this generates a lot of backtracking.
Is it possible to write such a test without additional arguments like counters?
I'm fairly sure it's not possible to write such a test (edit: that does a single pass through the list) without tracking additional information such as a counter or a stack. This is because the language you are parsing is a proper context-free language as opposed to a regular one. Parsing context-free languages requires some sort of unbounded state representation, while regular languages get away with finite states.
You would typically handle that extra state using arguments. Possibly hidden ones using definite clause grammars (DCGs). But here -- and I very strongly suggest you do not use this for anything -- is a way of storing that state not in an extra argument but at the head of the list itself.
First, make sure we are using useful syntax for parsing:
:- set_prolog_flag(double_quotes, chars).
This means that anything between double quotes will get interpreted as a list of characters, so you can write "(()" equivalently to the very unreadable ['(', '(', ')'].
Here is the code itself:
checkbrackets([]).
checkbrackets(['(' | Xs]) :-
checkbrackets([count(1) | Xs]).
checkbrackets([count(0)]).
checkbrackets([count(N), '(' | Xs]) :-
N1 is N + 1,
checkbrackets([count(N1) | Xs]).
checkbrackets([count(N), ')' | Xs]) :-
N > 0,
N1 is N - 1,
checkbrackets([count(N1) | Xs]).
This "replaces" the first opening parenthesis with a counter initialized to 1. It increments and decrements that counter as it consumes other opening or closing parentheses. At every update of the counter, the new value is pushed to the front of the list that is passed into the recursive call. The predicate succeeds when all parentheses in the list have been consumed and the counter is at exactly 0. (You don't say if you want to accept ()() or not. This implementation resolves this ambiguity in a particular way that might not be what you intended.)
Examples:
?- checkbrackets("").
true.
?- checkbrackets("(()(()))").
true ;
false.
?- checkbrackets("()(()))").
false.
?- checkbrackets("(()(())").
false.
You could use the same trick to parse more complicated languages that need more complex state than a single counter. But you shouldn't. DCGs are the best way to do this in Prolog.
Note that the implementation above does accept a list that is not purely a list of parentheses:
?- checkbrackets([count(0)]).
true ;
false.
It's possible to fix this, but you shouldn't, since you shouldn't use this approach at all.
checkbrackets([]).
checkbrackets(L):-
append(Sub1,['(',')'|Sub2],L),
!,
append(Sub1,Sub2,New),
checkbrackets(New).
It does need only one attribute and checks in square time. Not as fast as Willems or Isabelles code but works.
The idea is that in each valid bracket constellation there is at least once the pattern of one opening and one closing bracket next to each other. Find them, delete them, repeat.
I'm using Haskell to find a list of integers from 1 to 10000 that have a special property. I do the following
[ number | number <- [1..10000], (isSpecial number)]
However, every now and then I came up with some special properties that are
hard to be satisfied
take a long time to be verified
As a result, it hangs there after some first few examples.
I wonder how I can make the list comprehension in Haskell verbose, so I have a good update about how much Haskell has progressed.
This is more or less what Robin Zigmond meant:
checkNumbers :: IO [Int]
checkNumbers = filterM check [1..10000]
where
check number = do
print $ "Checking number" <> show number
pure $ isSpecial number
This will print "Checking number x" before checking every number. Feel free to experiment with any other effects (or, in your words, "verbosity") within the check function.
Here is a way that requires no IO, instead relying on laziness and your programmer guess about which "side" of the condition happens more often. Just to have something to play with, here's a slightly slow function that checks if a number is a multiple of 10. The details of this function aren't important, feel free to skip it if anything doesn't make sense. I'm also going to turn on timing reporting; you'll see why later.
> isSpecial :: Int -> Bool; isSpecial n = last [1..10000000] `seq` (n `mod` 10 == 0)
> :set +s
(Add one 0 every five years.)
Now the idea will be this: instead of your list comprehension, we'll use partition to split the list into two chunks, the elements that match the predicate and the ones that don't. We'll print the one of those that has more elements, so we can keep an eye on progress; by the time it's fully printed, the other one will be fully evaluated and we can inspect it however we like.
> :m + Data.List
> (matches, nonMatches) = partition isSpecial [1..20]
(0.00 secs, 0 bytes)
> nonMatches
[1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19]
(12.40 secs, 14,400,099,848 bytes)
Obviously I can't portray this over StackOverflow, but when I did the above thing, the numbers in the nonMatches list slowly appeared on my terminal one-by-one, giving a pretty good indicator of where in the list it was currently thinking. And now, when you print matches, the full list is available more or less instantly, as you can see by the timing report (i.e. not another 12-second wait):
> matches
[10,20]
(0.01 secs, 64,112 bytes)
But beware!
It's important that matches and nonMatches have types which are not typeclass polymorphic (i.e. don't have types that start with Num a => ... or some other constraint). In the above example, I achieved this by making isSpecial monomorphic, which forces matches and nonMatches to be, too, but if your isSpecial is polymorphic, you should give a type signature for matches or nonMatches to prevent this problem.
Doing it this way will cause the entire nonMatches and matches lists to be realized in memory. This could be expensive if the original list being partitioned is very long. (But up to, say, a couple hundred thousand Ints is not particularly long for modern computers.)
Debug.Trace
You can have a look at Debug.Trace. It allows printing messages to the console. But as Haskell is lazy, controlling when printing happens is not so easy. And this is also not recommended for production:
Prelude Debug.Trace> import Debug.Trace
Prelude Debug.Trace> [x | x <- [1..10], traceShow (x, odd x) $ odd x]
(1,True)
[1(2,False)
(3,True)
,3(4,False)
(5,True)
,5(6,False)
(7,True)
,7(8,False)
(9,True)
,9(10,False)
]
We would usually want to see both the tried and the discovered numbers as the calculation goes on.
What I usually do is break up the input list into chunks of n elements, filter each chunk as you would the whole list, and convert each chunk into a pair of its head element and the filtered chunk:
chunked_result = [ (h, [n | n <- chunk, isSpecial n])
| chunk#(h:_) <- chunksOf n input]
Putting such result list through concatMap snd gives the original non-"verbose" option.
Adjusting the n value will influence the frequency with which the progress will be "reported" when the result list is simply printed, showing both the tried and the discovered numbers, with some inconsequential "noise" around them.
Using second concat . unzip on the chunks results list is somewhat similar to Daniel Wagner's partitioning idea (with caveats),(*) but with your set value of n, not just 1.
If there is an algorithmic slowdown innate to your specific problem, apply the orders of growth run time estimation analysis.
(*) to make it compatible we need to stick some seq in the middle somewhere, like
chunked_result = [ (last s `seq` last chunk, s)
| chunk <- chunksOf n input
let s = [n | n <- chunk, isSpecial n] ]
or something.
I'm having some (or a lot of) trouble with lists of lists in prolog.
So I have a list of numbers, say [5,6,1,3] as input.
The output should be [[5,25],[6,36],[1,1],[3,9]].
I already have a predicate that 'return's the 2 item lists (keep in mind that I'll have to change the get_squared_pair function to get some other relevant value):
get_squared_pair(Number, Result) :-
get_squared_value(Number, SquareValue),
Result = [Number, SquareValue].
get_squared_value(Number, Result) :-
Result is Number * Number.
Until here it's pretty logical. Now I need a predicate that recursively iterates though a list, adds the squared pair to a new list, and then returns this lists of lists. What I have right now is:
return_list([], 0).
return_list([Head | Tail], Result) :-
get_squared_pair(Head, Add),
append(Add,Result),
return_list(Tail, Result).
This doesn't work for a number of reasons, and it's mostly because I can't seem to figure out how the recursion actually works with lists, much less lists of lists. Also it's currently running in the wrong order which doesn't help.
I understand this might be a bit vague but I've tried googling my way out of this one but can't seem to translate what I find into my own problem very well.
Any help would be much appreciated!
Let's look at your get_squared_pair/2 first. Although it's working, it can be tidied up a bit which will also help understand how Prolog works. The primary mechanism of Prolog is unification, which is not the same as assignment which occurs in other languages. In unification, Prolog examines two terms and attempts to unify them by instantiating variables in one or both of the terms to make them match. There are some predicates in Prolog, like is/2 which are used to evaluate expressions in one argument, and then unify the first argument with that result.
Your first predicate, then, which you have written as:
get_squared_pair(Number, Result) :-
get_squared_value(Number, SquareValue),
Result = [Number, SquareValue].
get_squared_value(Number, Result) :-
Result is Number * Number.
Can be simplified in two ways. First, you can consolidate the get_squared_value/2 since it's just one line and doesn't really need its own predicate. And we'll rename the predicate so it's not imperative.
square_pair(Number, Square) :-
S is Number * Number, % Square the number
Square = [Number, S]. % Unify Square with the pair
Prolog can unify terms in the head of the clause, so you can avoid the redundant unification. So this is all you need:
square_pair(Number, [Number, Square]) :-
Square is Number * Number.
On to the main predicate, return_list/2. First, we'll rename this predicate to square_pairs. When doing recursion with lists, the most common pattern is to continue reducing a list until it is empty, and then a base case handles the empty list. Your implementation does this, but the base case is a little confused since the 2nd argument is an integer rather than a list:
square_pairs([], 0).
This really should be:
square_pairs([], []).
Your main predicate clause isn't making correct use of append/2. There are two forms of append in SWI Prolog: append/2 and append/3. You can look up what these do in the SWI Prolog online documentation. I can tell you that, in Prolog, you cannot change the value of a variable within a predicate clause once it's been instantiated except through backtracking. For example, look at the following sequence that might be in a predicate clause:
X = a, % Unify X with the atom 'a'
X = b, % Unify X with the atom 'b'
In this case, the second expression will always fail because X is already unified and cannot be unified again. However, if I have this:
foo(X), % Call foo, which unifies X with a value that makes 'foo' succeed
bar(X, Y), % Call bar, which might fail based upon the value of 'X'
In the above case, if bar(X, Y) fails, then Prolog will backtrack to the foo(X) call and seek another value of X which makes foo(X) succeed. If it finds one, then it will call bar(X, Y) again with the new value of X, and so on.
So append(Add, Result) does not append Add to Result yielding a new value for Result. In fact, append with two arguments says that the second list argument is the concatenation of all the elements of the first list, assuming the first argument is a list of lists, so the definition of append/2 doesn't match anyway.
When thinking about your recursion, realize that the argument lists are in one-to-one correspondence with each other. The head of the result list is the "square pair" for the head of the list in the first argument. Then, recursively, the tail of the 2nd argument is a list of the square pairs for the tail of the first argument. You just need to express that in Prolog. We can also use the technique I described above for unification within the head of the clause.
square_pairs([Head | Tail], [SqPair | SqTail]) :-
square_pair(Head, SqPair),
square_pairs(Tail, SqTail).
square_pairs([], []).
Now there's another simplification we can do, which is eliminate the square_pair/2 auxiliary predicate completely:
square_pairs([Head | Tail], [[Head, SqHead] | SqTail]) :-
SqHead is Head * Head,
square_pairs(Tail, SqTail).
square_pairs([], []).
There's a handy predicate in Prolog called maplist which can be used for defining a relationship which runs parallel between two lists, which is the scenario we have here. We can bring back the square_pair/2 predicate and use maplist:
square_pairs(Numbers, SquarePairs) :-
maplist(square_pair, Numbers, SquarePairs).
So you want to turn your list into another, such that each element (a number) is turned into a two-element list, the number and its square.
All you need to do is to tell that to Prolog. First, the second one:
turn_into_two(Num, [A,B]):-
what is A?
A is Num,
what is B? We just tell it to Prolog, too:
B is ... * ... .
Now, on to our list. A list [A|B] in Prolog consists of its head element A, and its tail B - unless it's an empty list [] of course. It doesn't matter what the list's elements are; a list is a list.
We need to account for all cases, or else we're not talking about lists but something else:
turn_list([], Res):-
so what is our result in case the list was empty? It should be empty as well, right?
Res = ... .
in the other case,
turn_list([A|B], Res):-
our result won't be empty, so it'll have its head and tail, correct?
Res = [C|D],
next we say what we know about the heads: the input list's head turns into that two elements list we've described above, right?
turn_into_two(A,C),
and then we say our piece about the tails. But what do we know about the tails? We know that one is the result of the conversion of the other, just as the whole list is:
turn_list( ... , ...) .
And that's it. Incidentally, what we've described, follows the paradigm of mapping. We could have used any other predicate in place of turn_into_two/2, and it would get called for each of the elements of the input list together with the corresponding element from the resulting list.
If I have a function
let rec function n =
if n<0 then []
else n-2 # function n-2 ;;
I get an error saying that the expression function n-2 is a list of int but it is expecting an int.
How do I concatenate the values to return all the n-2 values above zero as a list?
I cannot use the List module to fold.
Thanks
Your title asks how to concatenate lists, but your question seems rather different.
To concatenate lists, you can use the # operator. In many cases, code that depends on this operator is slower than it needs to be (something to keep in mind for later :-).
Here are some things I see wrong with the code you give:
a. You can't name a function function, because function is a keyword in OCaml.
b. If you use the # operator, you should have lists on both sides of it. As near as I can see, the thing on the left in your code is not a list.
c. Function calls have higher precedence than infix operators. So myfun n - 2 is parsed as (myfun n) - 2. You probably want something closer to myfun (n - 2).
Even with these changes, your code seems to generate a list of integers that are 2 apart, which isn't what you say you want. However, I can't understand what the function is actually supposed to return.
It seems like you are not concatenating lists, but concatenating ints instead. This is done by the :: operator. So your code would look like:
else (n-2)::(fun (n-2))
Although I could see this function possibly not producing the desired output if you put in negative numbers. For example if you pass through n = 1, n-2 will evaluate to -1 which is less than zero.