compare two equivalence classes (cont.) - graph

val compare : bool array array -> 'a list -> 'a list -> int
compare m generates the lexicographical order on list. I don't know how to fill ???
let rec compare m c c' =
match c with
| [] -> (match c' with
| [] -> 0
| _ :: _ -> -1)
| hd1 :: tl1 -> (match c' with
| [] -> 1
| hd2 :: tl2 -> ???
This is a function that I was trying to do by in a list of ints. but this function was not satisfy, it still missing to check in the rest of a list.
let cmp_classes m c c' =
match c, c' with
| i :: _, j :: _ ->
begin
match m.(i).(j), m.(j).(i) with
(* same class: there is a path between i and j, and between j and i *)
| true, true -> 0
(* there is a path between i and j *)
| true, false -> 1
(* there is a path between j and i *)
| false, true -> -1
(* i and j are not compareable *)
| false, false -> 0
end
| _ -> assert false
Could you please help me? Because when I tried with this function in int
let cmp_classes m i j =
match m.(i).(j), m.(j).(i) with
(* same class: there is a path between i and j, and between j and i *)
| true, true -> 0
(* there is a path between i and j *)
| true, false -> 1
(* there is a path between j and i *)
| false, true -> -1
(* i and j are not compareable *)
| false, false -> 0
it still not return the right order in data I test.
I have been doing this function many times, it is really stuck when I have to try again and again but not find out what is wrong. Please I need your help. Thank you

(* i and j are not compareable *)
| false, false -> 0
This is completely wrong if you are trying to make a topologic sort of your elements. You are saying that incomparable elements are equals which is complete nonsense and WILL confuse the sort algorithm.
If you want to have a real topological order you should follow these steps:
build an input list as the list containing only one representant per class; the output list is empty
until the input list is empty:
pick a random root (with no input edge) in the input list and remove it from the list
append (in any order) all elements the root representants in the output list
return the output list
Depending on the data-structures you are using, this algorithm can be more or less efficient, but your question is not enough precise for me to tell you more.

Related

Unbound value in recursive function (Beginner OCaml)

Code:
let isPrime x =
let checkZero d = match (x mod d, x mod d + 2, intRoot x < d) with
| (0,_,_) -> false
| (_,0,_) -> false
| (_,_,true) -> true
| _ -> checkZero (d + 6) in
match x with
| 0 -> false
| 1 -> true
| 2 -> true
| 3 -> true
| _ -> match (x mod 2, x mod 3) with
| (0,_) -> false
| (_,0) -> false
| _ -> checkZero 5
Error:
line 9, characters 24-33:
Error: Unbound value checkZero
Which refers to the recursive call checkZero (d+6)
I've tried placing the checkZero function as a let ... in in the final checkZero 5 call and added/removed the x parameter in the checkZero function in case there was an error with the definition.
(Running OCaml downloaded in the past week on OSX through homebrew)
If you want a function to be able to call itself you need to declare it as recursive:
let rec checkZero d ...

Unexpected output type

I am doing practice with F#. I am trying to create a simple program capable to find me out a couple of prime numbers that, summed together, equal a natural number input. It is the Goldbach conjecture. A single couple of primes will be enough. We will assume the input to be a even number.
I first created a function to check if a number is prime:
let rec isPrime (x: int) (i: int) :bool =
match x % i with
| _ when float i > sqrt (float x) -> true
| 0 -> false
| _ -> isPrime x (i + 1)
Then, I am trying to develop a function that (a) looks for prime numbers, (b) compare their sum with the input 'z' and (c) returns a tuple when it finds the two numbers. The function should not be correct yet, but I would get the reason behind this problem:
let rec sumPrime (z: int) (j: int) (k: int) :int * int =
match isPrime j, isPrime k with
| 0, 0 when j + k > z -> (0, 0)
| 0, 0 -> sumPrime (j + 1) (k + 1)
| _, 0 -> sumPrime j (k + 1)
| 0, _ -> sumPrime (j + 1) k
| _, _ -> if j + k < z then
sumPrime (j + 1) k
elif j + k = z then
(j, k)
The problem: even if I specified that the output should be a tuple :int * int the compiler protests, claiming that the expected output should be of type bool. When in trouble, I usually refer to F# for fun and profit, that i love, but this time I cannot find out the problem. Any suggestion is greatly appreciated.
Your code has three problems that I've spotted:
Your isPrime returns a bool (as you've specified), but your match expression in sumPrime is matching against integers (in F#, the Boolean value false is not the same as the integer value 0). Your match expression should look like:
match isPrime j, isPrime k with
| false, false when j + k > z -> (0, 0)
| false, false -> ...
| true, false -> ...
| false, true -> ...
| true, true -> ...
You have an if...elif expression in your true, true case, but there's no final else. By default, the final else of an if expression returns (), the unit type. So once you fix your first problem, you'll find that F# is complaining about a type mismatch between int * int and unit. You'll need to add an else condition to your final match case to say what to do if j + k > z.
You are repeatedly calling your sumPrime function, which takes three parameters, with just two parameters. That is perfectly legal in F#, since it's a curried language: calling sumPrime with two parameters produces the type int -> int * int: a function that takes a single int and returns a tuple of ints. But that's not what you're actually trying to do. Make sure you specify a value for z in all your recursive calls.
With those three changes, you should probably see your compiler errors go away.

Average calculating of consecutive list elements in OCaml

I am trying to write a function in OCaml that will calculate the average of consecutive elements in a list. For example with [1; 2; 3; 4] it should output [1; 2; 3]. It should take (1 + 2) / 2 and give 1 then take (2 + 3) / 2 and give 2 and so on.
The code I wrote, however, only returns [1; 2]:
let rec average2 xs = match xs with
|[] -> []
|x :: [] -> [x]
|x :: x' :: xs -> if xs = [] then [(x + x') / 2] else [(x + x') / 2] # (average2 xs)
Can you please tell me how to fix this. Thank you.
When you're doing x :: y :: l in a match, you're effectively taking out the elements of the list permanently.
So if you want to do an operation on pairs of elements, you need to put one back in.
Example:
You have a list of [1;2;3;4]
You want to operate on 1 and 2, in your match it will interpret as:
1 :: 2 :: [3;4]
If you continue without adding an element in, the next statement would be:
3 :: 4 :: []
which is not what you want.
To correct this, in your recurice call you need to do (average2 (x'::xs) and not just (average2 xs) because xs is the rest of the list after taking the elements out.
OCaml allows to bind a pattern p to a variable v using p as v (alias patterns):
let rec average2 = function
| x :: (y :: _ as tail) -> (x + y) / 2 :: (average2 tail)
| _ -> []
Above, y :: _ as tail destructures a list named tail as a non-empty list headed by y and having an arbitrary tail _, the value of which we don't care about.
Note that I also simplified your function so that you don't check whether _ is empty or not: recursion handles this for you here.
Also, when you have zero or one element in the list, you should return an empty list.
# average2 [ 10; 20; 30; 40];;
- : int list = [15; 25; 35]

Simplify a recursive function from 3 to 2 clauses

I am doing some exercises on F#, i have this function that calculate the alternate sum:
let rec altsum = function
| [] -> 0
| [x] -> x
| x0::x1::xs -> x0 - x1 + altsum xs;;
val altsum : int list -> int
The exercise consist in declare the same function with only two clauses...but how to do this?
The answer of mydogisbox is correct and work!
But after some attempts I found a smallest and readable solution of the problem.
let rec altsum2 = function
| [] -> 0
| x0::xs -> x0 - altsum2 xs
Example
altsum2 [1;2;3] essentially do this:
1 - (2 - (3 - 0)
it's is a bit tricky but work!
OFF TOPIC:
Another elegant way to solve the problem, using F# List library is:
let altsum3 list = List.foldBack (fun x acc -> x - acc) list 0;;
After the comment of phoog I started trying to solve the problem with a tail recursive function:
let tail_altsum4 list =
let pl l = List.length l % 2 = 0
let rec rt = function
| ([],acc) -> if pl list then -acc else acc
| (x0::xs,acc) -> rt (xs, x0 - acc)
rt (list,0)
This is also a bit tricky...substraction is not commutative and it's impossible think to revers with List.rev a long list...but I found a workaround! :)
To reduce the number of cases, you need to move your algorithm back closer to the original problem. The problem says to negate alternating values, so that's what your solution should do.
let altsum lst =
let rec altsumRec lst negateNext =
match lst with
| [] -> 0
| head::tail -> (if negateNext then -head else head) + altsumRec tail (not negateNext)
altsumRec lst false

Pattern matching functions in OCaml

Can everyone explain to me this piece of code ?
let safe_division n = function
| 0 -> failwith "divide by 0"
| m -> n / m
When I excute safeDiv 3 0 , what is the m and n in this case ?
In general case, when does the function match the first and second pattern ?
It is easy to see what this means once you realise that
let f x y z = e
is just a short-hand for
let f = function x -> function y -> function z -> e
That is, a function of n arguments actually is n nested functions of 1 argument. That representation is called "currying". It is what allows you to apply a function partially, e.g.
let g = f 3
returns a function of 2 arguments.
Of course, the short-hand above can be mixed freely with the explicit form on the right, and that's what your example does. You can desugar it into:
let safe_division = function n -> function
| 0 -> failwith "divide by 0"
| m -> n / m
When you execute safe_division 3 0, first, 3 is bound to the name n and the right-hand side of the declaration is then evaluated.
This is a function, so the next argument, 0, is matched against the different cases, in order. Here, it matches the first case, so the right-hand side is evaluated and an exception is thrown. In this case, the name m is never bound to anything.
If the second argument was, for example, 1, then it would have matched the second case (this case matches every possible value anyway, it's a default case), binding the name m to the value 1 and then returning the result of n / m.
let safe_division n
define a function which type is int -> ...
function
| 0 -> failwith "divide by 0"
| m -> n / m
define a function which type is int -> int
So the resulting type of the whole is int -> int -> int where n is the first argument, and m the second. The last int is the result.
let safe_division n = function
| 0 -> failwith "divide by 0"
| m -> n / m
is just equivalent to:
let safe_division n = fun x -> match x with
| 0 -> failwith "divide by 0"
| m -> n / m
Note fun and function are slightly different. See: Function definition.

Resources