I have the following code in OCaml.I have defined all necesar functions and tested them step by step the evalution should work good but I didn't succed to manipulate the variables inside of while.How can I make x,vn,v to change their value?I think I should rewrite the while like a rec loop but can't figure out exactly:
Here is the rest of code: http://pastebin.com/Ash3xw6y
Pseudocode:
input : f formula
output: yes if f valid
else not
begin:
V =set of prop variables
eliminate from f => and <=>
while (V is not empty)
choose x from V
V =V -{x}
replace f with f[x->true]&&f[x->false]
simplify as much as possible f
if f is evaluated with true then return true
else if (not f) is evaluated true then return false
end if
end while
return false
end
type bexp = V of
| string
| B of bool
| Neg of bexp
| And of bexp * bexp
| Or of bexp * bexp
| Impl of bexp * bexp
| Eqv of bexp * bexp
module StringSet=Set.make(String)
let is_valide f=
let v= stringset_of_list (ens f []) in (*set of all variables of f *)
let g= elim f in (*eliminate => and <=> *)
let quit_loop=ref false in
while not !quit_loop
do
let x=StringSet.choose v in
let vn=StringSet.remove x v in
if StringSet.is_empty vn=true then quit_loop:=true;
let h= And( replace x (B true) g ,replace x (B false) g)in
let j=simplify h in
if (only_bools j) then
if (eval j) then print_string "yes"
else print_string "not"
done
(New form)
let tautology f =
let rec tautology1 x v g =
let h= And( remplace x (B true) g ,remplace x (B false) g)in
let j= simplify h in
if not (only_bools j) then tautology (StringSet.choose (StringSet.remove x v) (StringSet.remove x v) j
else
if (eval1 j) then print_string "yes \n " else
if (eval1 (Neg (j))) then print_string "not \n";
in tautology1 (StringSet.choose (stringset_of_list (ens f [])) (stringset_of_list (ens f [])) (elim f);;
while loop belongs to imperative programming part in OCaml.
Basically, you can't modify immutable variables in while or for loops or anywhere.
To let a variable to be mutable, you need to define it like let var = ref .... ref is the keyword for mutables.
Read these two chapters:
https://realworldocaml.org/v1/en/html/a-guided-tour.html#imperative-programming
https://realworldocaml.org/v1/en/html/imperative-programming-1.html
You can define x,vn,v as refs, but I guess it will be ugly.
I suggest you think your code in a functional way.
Since you haven't placed functions ens etc here, I can't produce an example refine for u.
Related
In functional programming, what is the name (or name of the concept) of the following functional operator P?:
Given two functions f and g, and predicate function p, P(p, f, g) is the function
x → if (p(x)) f(x) else g(x)
I am wondering whether this operator has an established name, so that I can use that name in my code. (That is, I want to give P a conventional name.)
I would say it's the if operator lifted into the function monad.
For example in Haskell, you can literally do
import Control.Monad
let if' c t f = if c then t else f -- another common name is `ite`
let ifM = liftM3 if' -- admittedly the type of this is too generic
-- ^^^^^^^^^^
let example = ifM even (\x -> "t "++show x) (\x -> "f "++show x)
example 1 -- "f 1"
example 2 -- "t 2"
Another haskell example Point-wise conditional in Boolean library
cond :: (Applicative f, IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a -> f a
it takes Applicative that holds bool, two another Applicatives with values for True and False cases and produces Applicative result.
There are different types that are Applicative and function is just one of them.
> f = cond (\x -> x > 1) (\x -> x / 10) (\x -> x * 10)
> f 2.0
# 0.2
> f 0.13
#1.3
Optional value Maybe is another useful example
> cond (Just True) (Just 10) (Just 20)
# Just 10
> cond (Just True) (Just 10) Nothing
# Nothing
List is also Applicative
> cond [True, False, True] [10] [1, 2]
# [10,10,1,2,10,10]
> cond [True, False, True] [10] [1]
# [10, 1, 10]
> cond [True, False, True] [10] []
# []
I'm working on an implementation of prime decomposition in OCaml. I am not a functional programmer; Below is my code. The prime decomposition happens recursively in the prime_part function. primes is the list of primes from 0 to num. The goal here being that I could type prime_part into the OCaml interpreter and have it spit out when n = 20, k = 1.
2 + 3 + 7
5 + 7
I adapted is_prime and all_primes from an OCaml tutorial. all_primes will need to be called to generate a list of primes up to b prior to prime_part being called.
(* adapted from http://www.ocaml.org/learn/tutorials/99problems.html *)
let is_prime n =
let n = abs n in
let rec is_not_divisor d =
d * d > n || (n mod d <> 0 && is_not_divisor (d+1)) in
n <> 1 && is_not_divisor 2;;
let rec all_primes a b =
if a > b then [] else
let rest = all_primes (a + 1) b in
if is_prime a then a :: rest else rest;;
let f elem =
Printf.printf "%d + " elem
let rec prime_part n k lst primes =
let h elem =
if elem > k then
append_item lst elem;
prime_part (n-elem) elem lst primes in
if n == 0 then begin
List.iter f lst;
Printf.printf "\n";
()
end
else
if n <= k then
()
else
List.iter h primes;
();;
let main num =
prime_part num 1 [] (all_primes 2 num)
I'm largely confused with the reclusive nature with the for loop. I see that List.ittr is the OCaml way, but I lose access to my variables if I define another function for List.ittr. I need access to those variables to recursively call prime_part. What is a better way of doing this?
I can articulate in Ruby what I'm trying to accomplish with OCaml. n = any number, k = 1, lst = [], primes = a list of prime number 0 to n
def prime_part_constructive(n, k, lst, primes)
if n == 0
print(lst.join(' + '))
puts()
end
if n <= k
return
end
primes.each{ |i|
next if i <= k
prime_part_constructive(n - i, i, lst+[i], primes)
}
end
Here are a few comments on your code.
You can define nested functions in OCaml. Nested functions have access to all previously defined names. So you can use List.iter without losing access to your local variables.
I don't see any reason that your function prime_part_constructive returns an integer value. It would be more idiomatic in OCaml for it to return the value (), known as "unit". This is the value returned by functions that are called for their side effects (such as printing values).
The notation a.(i) is for accessing arrays, not lists. Lists and arrays are not the same in OCaml. If you replace your for with List.iter you won't have to worry about this.
To concatenate two lists, use the # operator. The notation lst.concat doesn't make sense in OCaml.
Update
Here's how it looks to have a nested function. This made up function takes a number n and a list of ints, then writes out the value of each element of the list multiplied by n.
let write_mults n lst =
let write1 m = Printf.printf " %d" (m * n) in
List.iter write1 lst
The write1 function is a nested function. Note that it has access to the value of n.
Update 2
Here's what I got when I wrote up the function:
let prime_part n primes =
let rec go residue k lst accum =
if residue < 0 then
accum
else if residue = 0 then
lst :: accum
else
let f a p =
if p <= k then a
else go (residue - p) p (p :: lst) a
in
List.fold_left f accum primes
in
go n 1 [] []
It works for your example:
val prime_part : int -> int list -> int list list = <fun>
# prime_part 12 [2;3;5;7;11];;
- : int list list = [[7; 5]; [7; 3; 2]]
Note that this function returns the list of partitions. This is much more useful (and functional) than writing them out (IMHO).
Why is the following code giving me that error?
Note that the is_sorted function returns either true or false
and make_move function returns a list of lists. e.g [[0,1,3,2],[1,0,2,3]]
let rec solve_helper b pos n r fn =
if n = 0 then b :: r :: fn (*fn is the final array with all paths*)
else match pos with
[] -> fn
|(h::t) -> if is_sorted h = true then h
else h :: r (* ERROR HERE: r is the temp array that contains 1 path*)
solve_helper b (make_moves h) (n-1) r
solve_helper b t (n-1) r (*tail recursion*)
;;
let solve_board b n = solver_helper b (make_moves b) n [] []
;;
new code:
let rec solve_helper b pos n r fn =
if n = 0 then r :: fn (*fn is the final array with all paths*)
else match pos with
[] -> fn
|(h::t) -> if is_sorted h = true then
let j = h :: r in
r :: fn
else
let u = h :: r in
let k = solve_helper b (make_moves h) (n - 1) r fn in
solve_helper b t (n - 1) r fn(*tail recursion*)
;;
let solve_board b n = solve_helper b (make_moves b) n [] []
;;
These lines of your code:
else h :: r (* ERROR HERE: r is the temp array that contains 1 path*)
solve_helper b (make_moves h) (n-1) r
solve_helper b t (n-1) r (*tail recursion*)
do not make sense as far as I can tell. They represent a call to a function named r with 10 arguments (two of which are the function r itself).
Possibly you need to edit your code to show exactly what the compiler is seeing.
If your code actually looks like this, you need to rethink this part. It reads like imperative code (a series of things to do) rather than functional code (an expression consisting of functions applied to arguments).
Is it possible to have nested if without else statements. I wrote the following useless program to demonstrate nested ifs. How do I fix this so it's correct in terms of syntax. lines 5 and 6 gives errors.
let rec move_helper b sz r = match b with
[] -> r
|(h :: t) ->
if h = 0 then
if h - 1 = sz then h - 1 ::r
if h + 1 = sz then h + 1 ::r
else move_helper t sz r
;;
let move_pos b =
move_helper b 3 r
;;
let g = move_pos [0;8;7;6;5;4;3;2;1]
You can't have if without else unless the result of the expression is of type unit. This isn't the case for your code, so it's not possible.
Here's an example where the result is unit:
let f x =
if x land 1 <> 0 then print_string "1";
if x land 2 <> 0 then print_string "2";
if x land 4 <> 0 then print_string "4"
You must understand that if ... then is an expression like any other. If no else is present, it must be understood as if ... then ... else () and thus has type unit. To emphasize the fact that it is an expression, suppose you have two functions f and g of type, say, int → int. You can write
(if test then f else g) 1
You must also understand that x :: r does not change r at all, it constructs a new list putting x in front of r (the tail of this list is shared with the list r). In your case, the logic is not clear: what is the result when h=0 but the two if fail?
let rec move_helper b sz r = match b with
| [] -> r
| h :: t ->
if h = 0 then
if h - 1 = sz then (h - 1) :: r
else if h + 1 = sz then (h + 1) :: r
else (* What do you want to return here? *)
else move_helper t sz r
When you have a if, always put an else. Because when you don't put an else, Java will not know if the case is true or false.
It is possible to improve "raw" Fibonacci recursive procedure
Fib[n_] := If[n < 2, n, Fib[n - 1] + Fib[n - 2]]
with
Fib[n_] := Fib[n] = If[n < 2, n, Fib[n - 1] + Fib[n - 2]]
in Wolfram Mathematica.
First version will suffer from exponential explosion while second one will not since Mathematica will see repeating function calls in expression and memoize (reuse) them.
Is it possible to do the same in OCaml?
How to improve
let rec fib n = if n<2 then n else fib (n-1) + fib (n-2);;
in the same manner?
The solution provided by rgrinberg can be generalized so that we can memoize any function. I am going to use associative lists instead of hashtables. But it does not really matter, you can easily convert all my examples to use hashtables.
First, here is a function memo which takes another function and returns its memoized version. It is what nlucaroni suggested in one of the comments:
let memo f =
let m = ref [] in
fun x ->
try
List.assoc x !m
with
Not_found ->
let y = f x in
m := (x, y) :: !m ;
y
The function memo f keeps a list m of results computed so far. When asked to compute f x it first checks m to see if f x has been computed already. If yes, it returns the result, otherwise it actually computes f x, stores the result in m, and returns it.
There is a problem with the above memo in case f is recursive. Once memo calls f to compute f x, any recursive calls made by f will not be intercepted by memo. To solve this problem we need to do two things:
In the definition of such a recursive f we need to substitute recursive calls with calls to a function "to be provided later" (this will be the memoized version of f).
In memo f we need to provide f with the promised "function which you should call when you want to make a recursive call".
This leads to the following solution:
let memo_rec f =
let m = ref [] in
let rec g x =
try
List.assoc x !m
with
Not_found ->
let y = f g x in
m := (x, y) :: !m ;
y
in
g
To demonstrate how this works, let us memoize the naive Fibonacci function. We need to write it so that it accepts an extra argument, which I will call self. This argument is what the function should use instead of recursively calling itself:
let fib self = function
0 -> 1
| 1 -> 1
| n -> self (n - 1) + self (n - 2)
Now to get the memoized fib, we compute
let fib_memoized = memo_rec fib
You are welcome to try it out to see that fib_memoized 50 returns instantly. (This is not so for memo f where f is the usual naive recursive definition.)
You pretty much do what the mathematica version does but manually:
let rec fib =
let cache = Hashtbl.create 10 in
begin fun n ->
try Hashtbl.find cache n
with Not_found -> begin
if n < 2 then n
else
let f = fib (n-1) + fib (n-2) in
Hashtbl.add cache n f; f
end
end
Here I choose a hashtable to store already computed results instead of recomputing them.
Note that you should still beware of integer overflow since we are using a normal and not a big int.