I'm using the OCaml interface of the Apron library.
When I want to reduce the expression [| x + y -2 >= 0; x + y > - 3=0|], the result of tab is [|-3 + 1 * x + 1 * y >= 0|], How can I get the origin expression x + y - 3 >= 0?
let _ =
let vx = Var.of_string "x" in
let vy = Var.of_string "y" in
let env = Environment.make [||] [|vx;vy|] in
let c = Texpr1.cst env (Coeff.s_of_int 2) in
let c' = Texpr1.cst env (Coeff.s_of_int 3) in
let vx' = Texpr1.var env vx in
let vy' = Texpr1.var env vy in
let texpr = Texpr1.binop Add vx' vy' Real Near in
let texpr1 = Texpr1.binop Sub texpr c Real Near in
let texpr2 = Texpr1.binop Sub texpr c' Real Near in
(* let sum' = Texpr1.(Binop(Sub,x2,Cst c,Int,Near)) in *)
Format.printf "env = %a#." (fun x -> Environment.print x) env;
Format.printf "expr = %a#." (fun x -> Texpr1.print x) texpr;
let cons1 = Tcons1.make texpr1 Lincons0.SUPEQ in
let cons2 = Tcons1.make texpr2 Lincons0.SUPEQ in
let tab = Tcons1.array_make env 2 in
Tcons1.array_set tab 0 cons1;
Tcons1.array_set tab 1 cons2;
let abs = Abstract1.of_tcons_array manpk env tab in
let tab' = Abstract1.to_tcons_array manpk abs in
Format.printf "tab = %a#." (fun x -> Tcons1.array_print x) tab;
Format.printf "tab1 = %a#." (fun x -> Tcons1.array_print x) tab'
It seems to me that there is no inconsistency as the expressions -3 + 1 * x + 1 * y >= 0 and x + y - 3 >= 0 are semantically equivalent.
Why is the expression printed this way?
You are building a polyhedron (i'm guessing manpk refers to the polka manager) and even if it is built using tree-constraints, it is represented internally using linear-constraints. So when you convert it back to tree-constraints, you actually are converting a Lincons1.earray to a Tcons1.earray, hence the representation as a sum of monoms.
If by "get the origin expression" you mean, make Apron print it in a human friendly way, i suggest you convert your polyhedron to a linear-constraint array (using to_lincons_array) and then define your own pretty-printing utility over linear constraints.
Alternatively, you can use the Apronext library, which is a small wrapper I wrote around the Apron library which provides pp_print functions. On your specific example, using Linconsext.pp_print, you get: x+y>=3. Disclaimer, Apronext is neither efficient, nor reliable, nor maintained, so i suggest you dont use it extensively, but only for understanding purposes
Related
I have some functions that call other functions and I want to print the nested calls to see what's happening.
Let's take this minimum example:
let a x = x + 1
let b x = x + 1
let f x =
let res_a1 = a x in
let res_b = b x in
let res_a2 = a x in
res_a1 + res_b + res_a2
let () = ignore (f 1)
To print what's happening I wrote the following:
let a x =
Format.printf "a#,";
x + 1
let b x =
Format.printf "b#,";
x + 1
let f x =
Format.printf "#[<v 2>[f#,";
let res_a1 = a x in
let res_b = b x in
let res_a2 = a x in
Format.printf "#]#,]#,";
res_a1 + res_b + res_a2
let () =
Format.printf "#[<v 0>";
ignore (f 1);
Format.printf "#."
The issue it that I have an extra break that I needed to add to have the closing ] properly indented (in my real case I don't know when a nested call is the last call so I can't just not print the #, in the last call):
[f
a
b
a
]
If I instead write Format.printf "#]]#,"; then I won't have the extra break but the closing ] will not be properly indented:
[f
a
b
a
]
Is there a way to tell Format to properly indent ] without adding an extra break?
Namely, I'd like to have:
[f
a
b
a
]
This is an example of a common problem when you need to print a list of objects interspersed by a separator. If you add a separator after each element you will have an ugly trailing separator. In case the separator is a newline itself, it will also mess with your indentation.
The common solution is to give special treatment to the last element, which doesn't work in your case. However, in your case, it is totally fine to add a separator before each element.
let a x =
Format.printf "#,a";
x + 1
let b x =
Format.printf "#,b";
x + 1
let f x =
Format.printf "[#[<v2>f";
let res_a1 = a x in
let res_b = b x in
let res_a2 = a x in
Format.printf "#]#,]";
res_a1 + res_b + res_a2
let () =
Format.printf "#.";
Format.printf "#[<v0>";
ignore (f 1);
Format.printf "#]#."
which gives us proper,
[f
a
b
a
]
Note, that the underlying reason why your code was giving an improper indentation is that you were issuing a break inside of the v2 box in the last call, so it will be always indented with +2.
Locked. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
I have a problem on my program, when I call on the Ocaml terminal "#matrix81 cache;;" it gives me the error: "This expression has type cache list but is here used with type cache list"
This is my code. Any help?
let rec makeLine w =
let y = w - 1 in
if w <> 0 then 0::(makeLine y)
else []
;;
let rec makeMatrix w h =
let y = h - 1 in
if h <> 0 then (makeLine w)::(makeMatrix w y)
else []
;;
let rec checkCache lc d t =
match lc with
[] -> 0
|x::xs -> if (x.difficulty = d) && (x.terrain = t) then (checkCache xs d t) + 1
else (checkCache xs d t)
;;
let rec checkLine lc d t line =
match line with
[]->[]
|x::xs -> let nt = t +. 0.5 in
let v = 5.0 in
if (nt < v) then
let nx = (checkCache lc d t) in
(nx)::(checkLine lc d nt xs)
else []
;;
let rec matrix81Aux m d lc =
match m with
[] -> []
|x::xs -> let nd = d +. 0.5 in
let v = 5.0 in
if (nd < v) then
(checkLine lc d 1.0 x)::(matrix81Aux xs nd lc)
else []
;;
let matrix81 lc =
let m = makeMatrix 9 9 in
matrix81Aux m 1.0 lc
;;
You don't show the definition of the type cache (or give the line number for the error).
The most common cause of this strange type of error message is that you have defined the same type name twice. This often happens when working from the toplevel and loading files with #use.
It's also possible you're defining the name cache twice some other way.
Recent versions of OCaml add an integer to the type name, to (try to) clarify that two different types are involved:
# type cache = A | B;;
type cache = A | B
# let f = function A -> 3 | B -> 4;;
val f : cache -> int = <fun>
# type cache = C | D;;
type cache = C | D
# let g x = match x with C -> f x | D -> 14;;
Error: This expression has type cache/1023
but an expression was expected of type cache/1018
Can someone explain the syntax used for when you have nested functions?
For example I have a outer and an inner recursive function.
let rec func1 list = match list with
[] -> []
|(head::tail) ->
let rec func2 list2 = match list2 with
...
;;
I have spent all day trying to figure this out and I'm getting a ever tiring "Syntax error".
You don't show enough code for the error to be obvious.
Here is a working example:
# let f x =
let g y = y * 5 in
g (x + 1);;
val f : int -> int = <fun>
# f 14;;
- : int = 75
Update
Something that might help until you're used to OCaml syntax is to use lots of extra parentheses:
let rec f y x =
match x with
| h :: t -> (
let incr v = if h = y then 1 + v else v in
incr (f y t)
)
| _ -> (
0
)
It's particularly hard to nest one match inside another without doing this sort of thing. This may be your actual problem rather than nested functions.
I have a simple code of union-find as below:
let rec find p x =
if p.(x) = x
then x
else
let y = find p (p.(x)) in
p.(x) <- y;
y;;
let union x y p =
p.(find p y) <- p.(find p x);
p
Example:
let a = [|0;1;2;3;4|]
let print_array a =
Array.iter (fun i -> Printf.printf "%i" i; print_string " ") a
let print_union =
let a = union 0 1 a in
print_string "Result union (0, 1): ";
print_array a;
print_string "\n"
the result will be:
Result union (0, 1): 0 0 2 3 4
I am having a hard time to go further to get the disjoint-set.
For instance the example above I want to get: {0,1},{2},{3},{4}
Thank you for your help.
For obvious reasons, you can't print that result without going through the whole structure.
So, you want to collect inhabitants from all of your union-find:
let print_classes a =
(* Let's first create an array for storing the classes *)
let classes = Array.make (Array.length a) [] in
(* Let's now populate it!
I'm going backwards in the array to have nicer printing *)
for i = (Array.length classes) - 1 downto 0
do classes.(a.(i)) <- i :: (classes.(a.(i))) done;
(* And now the printing *)
Array.iter (function
| [] -> ()
| h::t -> Printf.printf "{%d%a}" h
(fun c -> List.iter (fun x -> Printf.fprintf c ",%i" x)) t
)
classes
I used Printf functions for the sake of brevity, you can find their doc here.
Note that this could probably be improved as it creates a potentially big array that may be "almost not" populated. depending on the frequency in which you'll use this function, you may want to store the equivalence class along with the class leader (I had to do that once, I used Set and Map from the stdlib).
I am writing a function that swaps the contents of two reference calls.
let swap (x : a ref) (y :'a ref) : unit =
where
type 'a ref = {mutable contents : 'a}
I do not know what approach to take in order to solve this. Do I use pattern matching?
This is my test case
let test () : bool =
let r1 = { contents = 5 } in
let r2 = { contents = 6 } in
let _ = swap r1 r2 in
(6, 5) = (r1.contents, r2.contents)
;;
run_test "Swap different" test
Does this work?
let swap x y =
let z = !x in
x := !y;
y := z
Note that := and ! are just normal functions like so:
let (:=) r x = r.contents <- x
let (!) {contents} = contents
If you want to use own your type definition then you can do:
let swap' x y =
let z = x.contents in
x.contents <- y.contents;
y.contents <- z
Finally, if you're using batteries then you can just use BatRef.swap as defined here: http://ocaml-batteries-team.github.com/batteries-included/hdoc2/BatRef.html