Error while using Z3 module in OCaml - ocaml

I am new to OCaml. I installed Z3 module as mentioned in this link
I am calling Z3 using the command:
ocamlc -custom -o ml_example.byte -I ~/Downloads/z3-unstable/build/api/ml -cclib "-L ~/Downloads/z3-unstable/build/ -lz3" nums.cma z3ml.cma $1
where $1 is replaced with file name.
type loc = int
type var = string
type exp =
| Mul of int * exp
| Add of exp * exp
| Sub of exp * exp
| Const of int
| Var of var
type formula =
| Eq of exp * exp
| Geq of exp
| Gt of exp
type stmt =
| Assign of var * exp
| Assume of formula
type transition = loc * stmt * loc
module OrdVar =
struct
type t = var
let compare = Pervasives.compare
end
module VarSets = Set.Make( OrdVar )
type vars = VarSets.t
module OrdTrans =
struct
type t = transition
let compare = Pervasives.compare
end
module TransitionSets = Set.Make( OrdTrans )
type transitionSet = TransitionSets.t
type program = vars * loc * transitionSet * loc
let ex1 () : program =
let vset = VarSets.empty in
let vset = VarSets.add "x" vset in
let vset = VarSets.add "y" vset in
let vset = VarSets.add "z" vset in
let ts = TransitionSets.empty in
(* 0 X' = X + 1 *)
let stmt1 = Assign( "x", Add( Var("x"), Const(1) ) ) in
let tr1 = (0,stmt1,1) in
let ts = TransitionSets.add tr1 ts in
(vset,0,ts,10)
In the above code I am defining some types. Now if I include the command "open Z3", I am getting "Error: Unbound module Set.Make".
I could run test code which uses Z3 module with out any difficulty, but unable to run with the above code.

The error message in this case is a little bit confusing. The problem is that Z3 also provides a module called Set, which doesn't have a make function. This can be overcome simply by not importing everything from Z3, as there are a number of modulse that might clash with others. For example,
open Z3.Expr
open Z3.Boolean
will work fine and opens only the Z3.Expr and Z3.Boolean modules, but not the Z3.Set module. so that we can write an example function:
let myfun (ctx:Z3.context) (args:expr list) =
mk_and ctx args
If Z3.Boolean is not opened, we would have to write Z3.Boolean.mk_and instead, and similarly we can still access Z3's Set module functions by prefixing them with Z3.Set.

Related

Creating a serializable fixed size char array in F#

I am dealing with a very large amount of data I need to load / save to disk where speed is the key.
I wrote this code:
// load from cache
let loadFromCacheAsync<'a when 'a: (new: unit -> 'a) and 'a: struct and 'a :> ValueType> filespec =
async {
let! bytes = File.ReadAllBytesAsync(filespec) |> Async.AwaitTask
let result =
use pBytes = fixed bytes
let sourceSpan = Span<byte>(NativePtr.toVoidPtr pBytes, bytes.Length)
MemoryMarshal.Cast<byte, 'a>(sourceSpan).ToArray()
return result
}
// save to cache
let saveToCacheAsync<'a when 'a: unmanaged> filespec (data: 'a array) =
Directory.CreateDirectory cacheFolder |> ignore
let sizeStruct = sizeof<'a>
use ptr = fixed data
let nativeSpan = Span<byte>(NativePtr.toVoidPtr ptr, data.Length * sizeStruct).ToArray()
File.WriteAllBytesAsync(filespec, nativeSpan) |> Async.AwaitTask
and it requires the data structures to be unmanaged.
For example, I have:
[<Struct>]
[<StructLayout(LayoutKind.Explicit)>]
type ShortTradeData =
{
[<FieldOffset(00)>] Timestamp: DateTime
[<FieldOffset(08)>] Price: double
[<FieldOffset(16)>] Quantity: double
[<FieldOffset(24)>] Direction: int
}
or
[<Struct>]
[<StructLayout(LayoutKind.Explicit)>]
type ShortCandleData =
{
[<FieldOffset(00)>] Timestamp: DateTime
[<FieldOffset(08)>] Open: double
[<FieldOffset(16)>] High: double
[<FieldOffset(24)>] Low: double
[<FieldOffset(32)>] Close: double
}
etc...
I'm now facing a case where I need to store a string. I know the max length of the strings but I'm trying to find out how I can do this with un-managed types.
I'm wondering if I could do something like this (for 256 bytes):
[<Struct>]
[<StructLayout(LayoutKind.Explicit)>]
type TestData =
{
[<FieldOffset(00)>] Timestamp: DateTime
[<FieldOffset(08)>] Text: char
[<FieldOffset(264)>] Dummy: int
}
Would it be safe then to get a pointer to Text, cast it to a char array, read / write what I want in it and then save / load it as needed?
Or am I asking for some random troubles at some point?
As a side question, any way to speed up the loadFromCache function is very welcome too :)
Edit:
I came up with this for now. It converts a list of complex event objects into something serializable.
The line:
let bytes = Pipeline.serializeBinary event
turns the original event data into a byte array.
Then I create the struct that will hold the binary stream, write the length, create a span representing the struct and copy the bytes. Then I marshal the span into the struct type (ShortEventData).
I can't use Marshal copy since I can't put a destination offset, so I have to copy the bytes with a loop. But there has to be a better way.
And I think, there has to be a better way for everything else in this as well :D Any suggestion would help, I just don't really like this solution.
[<Struct>]
[<StructLayout(LayoutKind.Explicit)>]
type ShortEventData =
{
[<FieldOffset(00)>] Timestamp: DateTime
[<FieldOffset(08)>] Event: byte
[<FieldOffset(1032)>] Length: int
}
events
|> List.map (fun event ->
let bytes = Pipeline.serializeBinary event
let serializableEvent : DataCache.ShortEventData =
{
Timestamp = event.GetTimestamp()
Event = byte 0
Length = bytes.Length
}
use ptr = fixed [|serializableEvent|]
let nativeSpan = Span<byte>(NativePtr.toVoidPtr ptr, serializableEvent.Length * sizeStruct)
for i = 0 to bytes.Length - 1 do
nativeSpan[8 + i] <- bytes[i]
MemoryMarshal.Cast<byte, DataCache.ShortEventData>(nativeSpan).ToArray()[0]
)
Edit:
Adding benchmarks for different serialization models:
open System
open System.IO
open System.Runtime.InteropServices
open BenchmarkDotNet.Attributes
open BenchmarkDotNet.Running
open MBrace.FsPickler
open Microsoft.FSharp.NativeInterop
open Newtonsoft.Json
#nowarn "9"
[<Struct>]
[<StructLayout(LayoutKind.Explicit)>]
type TestStruct =
{
[<FieldOffset(00)>] SomeValue: int
[<FieldOffset(04)>] AnotherValue: int
[<FieldOffset(08)>] YetAnotherValue: double
}
static member MakeOne(r: Random) =
{
SomeValue = r.Next()
AnotherValue = r.Next()
YetAnotherValue = r.NextDouble()
}
[<MemoryDiagnoser>]
type Benchmarks () =
let testData =
let random = Random(1000)
Array.init 1000 (fun _ -> TestStruct.MakeOne(random))
// inits, outside of the benchmarks
// FSPickler
let FSPicklerSerializer = FsPickler.CreateBinarySerializer()
// APEX
let ApexSettings = Apex.Serialization.Settings().MarkSerializable(typeof<TestStruct>)
let ApexBinarySerializer = Apex.Serialization.Binary.Create(ApexSettings)
[<Benchmark>]
member _.Thomas() = // thomas' save to disk
let sizeStruct = sizeof<TestStruct>
use ptr = fixed testData
Span<byte>(NativePtr.toVoidPtr ptr, testData.Length * sizeStruct).ToArray()
[<Benchmark>]
member _.Newtonsoft() =
JsonConvert.SerializeObject(testData)
[<Benchmark>]
member _.FSPickler() =
FSPicklerSerializer.Pickle testData
[<Benchmark>]
member _.Apex() =
let outputStream = new MemoryStream()
ApexBinarySerializer.Write(testData, outputStream)
[<EntryPoint>]
let main _ =
let _ = BenchmarkRunner.Run<Benchmarks>()
0
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|----------- |-------------:|-------------:|-------------:|---------:|--------:|--------:|----------:|
| Thomas | 878.4 ns | 11.74 ns | 10.41 ns | 2.5444 | 0.1411 | - | 16 KB |
| Newtonsoft | 880,641.2 ns | 16,346.50 ns | 15,290.52 ns | 103.5156 | 79.1016 | 48.8281 | 508 KB |
| FSPickler | 71,786.6 ns | 1,373.89 ns | 1,349.35 ns | 13.6719 | 2.0752 | - | 84 KB |
| Apex | 1,088.8 ns | 20.59 ns | 22.03 ns | 2.6093 | 0.0725 | - | 16 KB |
It looks like Apex is very close to what I did, but it's probably a lot more flexible and more optimized, so it could make sense to switch to it, UNLESS what I have can be a lot more optimized.
I have to see how #JL0PD's excellent comments can improve the speed.
Out of interest I took the lambda at the end of your question and tested three similar implementations and ran it on Benchmark.Net.
Reference - as you have shown
Mutable Struct - as I might have done it with a mutable struct
Record - using a plain old dumb record
See the results for yourself. Plain old dumb record is the fastest (though only marginally faster than my attempt and ~10x faster than your example). Write dumb code first. Benchmark it. Then try to improve.
#nowarn "9"
open System
open System.Runtime.InteropServices
open BenchmarkDotNet.Attributes
open BenchmarkDotNet.Running
open Microsoft.FSharp.NativeInterop
type ShortEventDataRec =
{
Timestamp: DateTime
Event: byte[]
Length: int
}
[<Struct>]
[<StructLayout(LayoutKind.Explicit)>]
type ShortEventData =
{
[<FieldOffset(00)>] Timestamp: DateTime
[<FieldOffset(08)>] Event: byte
[<FieldOffset(1032)>] Length: int
}
[<StructLayout(LayoutKind.Explicit)>]
type MutableShortEventData =
struct
[<FieldOffset(00)>] val mutable Timestamp: DateTime
[<FieldOffset(08)>] val mutable Event: byte
[<FieldOffset(1032)>] val mutable Length: int
end
[<MemoryDiagnoser>]
type Benchmarks () =
let event =
Array.init 1024 (fun i -> byte (i % 256))
let time = DateTime.Now
let sizeStruct = sizeof<ShortEventData>
[<Benchmark>]
member __.Reference() =
let bytes = event
let serializableEvent =
{
ShortEventData.Timestamp = time
Event = byte 0
Length = bytes.Length
}
use ptr = fixed [|serializableEvent|]
let nativeSpan = Span<byte>(NativePtr.toVoidPtr ptr, sizeStruct)
for i = 0 to bytes.Length - 1 do
nativeSpan.[8 + i] <- bytes.[i]
MemoryMarshal.Cast<byte, ShortEventData>(nativeSpan).[0]
[<Benchmark>]
member __.MutableStruct() =
let bytes = event
let targetBytes = GC.AllocateUninitializedArray(sizeStruct)
let targetSpan = Span(targetBytes)
let targetStruct = MemoryMarshal.Cast<_, MutableShortEventData>(targetSpan)
targetStruct.[0].Timestamp <- time
let targetEvent = bytes.CopyTo(targetSpan.Slice(8, 1024))
targetStruct.[0].Length <- event.Length
targetStruct.[0]
[<Benchmark>]
member __.Record() =
let bytes = event
let serializableEvent =
{
ShortEventDataRec.Timestamp = time
Event =
let eventBytes = GC.AllocateUninitializedArray(bytes.Length)
System.Array.Copy(bytes, eventBytes, bytes.Length)
eventBytes
Length = bytes.Length
}
serializableEvent
[<EntryPoint>]
let main _ =
let _ = BenchmarkRunner.Run<Benchmarks>()
0
Method
Mean
Error
StdDev
Gen 0
Gen 1
Allocated
Reference
526.88 ns
6.318 ns
5.909 ns
0.0629
-
1 KB
MutableStruct
49.50 ns
0.966 ns
1.074 ns
0.0636
-
1 KB
Record
42.73 ns
0.672 ns
0.628 ns
0.0650
0.0002
1 KB

How to force any decimal value (be it part of a type or not) generated with fscheck to be within a certain range?

I'm using fscheck to write some unite tests and I would like to narrow down the range of decimal automatically generated and that regardless of the parameter I'm passing. What I mean by that is that let's say I have the types below:
decimal
DecimalHolder
Nested records containing decimal fields
DU with cases with decimal fields
Without having something to define an arbitrary for each single type, just that down the line in the generation if there a decimal it must say be between 0 and 300,000.
module Tests
open Xunit
open FsCheck.Xunit
open Swensen.Unquote
let addDecimals a b: decimal =
a + b
[<Property>]
let ``test adding two decimals`` a b =
let actual = addDecimals a b
let expected = a + b
test<# actual = expected #>
type DecimalHolder =
{ Value: decimal }
let addDecimalHolders a b =
{ Value = a.Value + b.Value }
[<Property>]
let ``test adding two decimal holders`` a b =
let actual = addDecimalHolders a b
let expected = { Value = a.Value + b.Value }
test<# actual = expected #>
type DecimalStuff =
| Value of decimal
| Holder of DecimalHolder
| Holders of DecimalHolder list
// Whatever
etc.
How can I achieve that?
Ok actually the Arbitrary definition works recursively across parameters types was enough:
module Tests
open Xunit
open FsCheck.Xunit
open Swensen.Unquote
type NotBigPositiveDecimalArbitrary =
static member NotBigPositiveDecimal() =
Gen.choose (1, 500)
|> Gen.map (fun x -> decimal x)
|> Arb.fromGen
let addDecimals a b: decimal =
a + b
[<Property(Arbitrary = [| typeof<NotBigPositiveDecimalArbitrary> |])>]
let ``test adding two decimals`` a b =
let actual = addDecimals a b
let expected = a + b
test<# actual = expected #>
type DecimalHolder =
{ Value: decimal }
let addDecimalHolders a b =
{ Value = a.Value + b.Value }
[<Property(Arbitrary = [| typeof<NotBigPositiveDecimalArbitrary> |])>]
let ``test adding two decimal holders`` a b =
let actual = addDecimalHolders a b
let expected = { Value = a.Value + b.Value }
test<# actual = expected #>

Define a closure variable in buckle script

I'm trying to convert the following ES6 script to bucklescript and I cannot for the life of me figure out how to create a "closure" in bucklescript
import {Socket, Presence} from "phoenix"
let socket = new Socket("/socket", {
params: {user_id: window.location.search.split("=")[1]}
})
let channel = socket.channel("room:lobby", {})
let presence = new Presence(channel)
function renderOnlineUsers(presence) {
let response = ""
presence.list((id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
response += `<br>${id} (count: ${count})</br>`
})
document.querySelector("main[role=main]").innerHTML = response
}
socket.connect()
presence.onSync(() => renderOnlineUsers(presence))
channel.join()
the part I cant figure out specifically is let response = "" (or var in this case as bucklescript always uses vars):
function renderOnlineUsers(presence) {
let response = ""
presence.list((id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
response += `<br>${id} (count: ${count})</br>`
})
document.querySelector("main[role=main]").innerHTML = response
}
the closest I've gotten so far excludes the result declaration
...
...
let onPresenceSync ev =
let result = "" in
let listFunc = [%raw begin
{|
(id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
result += `${id} (count: ${count})\n`
}
|}
end
] in
let _ =
presence |. listPresence (listFunc) in
[%raw {| console.log(result) |} ]
...
...
compiles to:
function onPresenceSync(ev) {
var listFunc = (
(id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
result += `${id} (count: ${count})\n`
}
);
presence.list(listFunc);
return ( console.log(result) );
}
result is removed as an optimization beacuse it is considered unused. It is generally not a good idea to use raw code that depends on code generated by BuckleScript, as there's quite a few surprises you can encounter in the generated code.
It is also not a great idea to mutate variables considered immutable by the compiler, as it will perform optimizations based on the assumption that the value will never change.
The simplest fix here is to just replace [%raw {| console.log(result) |} ] with Js.log result, but it might be enlightening to see how listFunc could be written in OCaml:
let onPresenceSync ev =
let result = ref "" in
let listFunc = fun [#bs] id item ->
let count = Js.Array.length item##meta in
result := {j|$id (count: $count)\n|j}
in
let _ = presence |. (listPresence listFunc) in
Js.log !result
Note that result is now a ref cell, which is how you specify a mutable variable in OCaml. ref cells are updated using := and the value it contains is retrieved using !. Note also the [#bs] annotation used to specify an uncurried function needed on functions passed to external higher-order functions. And the string interpolation syntax used: {j| ... |j}

How to create a Hashtbl with a custom type as key?

I'm trying to create a Hashtbl with a node type I've written.
type position = float * float
type node = position * float
I'd like to create a Hashtbl with nodes as keys pointing to a float, and have something like this :
[((node), float))]
This is what I've tried so far :
module HashtblNodes =
struct
type t = node
let equal = ( = )
let hash = Hashtbl.hash
end;;
Along with :
module HashNodes = Hashtbl.Make(HashtblNodes);;
I'm not sure it's the right implementation to do what I explained before, plus I don't know how I could create the table with this.
How would I be able to do this please?
Your approach just works (though see a comment to your question about "you don't actually need to use the functor").
Starting from your definitions in the question:
# let tbl = HashNodes.create 1 ;;
val tbl : '_weak2 HashNodes.t = <abstr>
# let node1 = ((1.0, 2.0), 3.0);;
val node1 : (float * float) * float = ((1., 2.), 3.)
# let node2 = ((-1.0, -2.0), -3.0);;
val node2 : (float * float) * float = ((-1., -2.), -3.)
# HashNodes.add tbl node1 100.0;;
- : unit = ()
# HashNodes.add tbl node2 200.0;;
- : unit = ()
# HashNodes.find tbl ((1.0, 2.0), 3.0) ;;
- : float = 100.
#

OCaml: Read a specific line in a file

my problem is simple, i want to read the third line in a file. This is my code, I think it should work.
But it doesn't ... Can someone please explain for me why??
open Printf
let filename = "T:\\Soton Uni\\ok.txt"
let () =
let ic = open_in filename in
let line_counter = 0 in
try
while true; do
line_counter = line_counter + 1;
let line = input_line ic in
if line_counter = 3 then
print_endline line;
done;
flush stdout;
close_in ic
with e ->
close_in_noerr ic;;
Variables in OCaml are never mutable — they can refer to mutable data, but what the variable points to can't be changed.
Therefore, the imperative style variable initialize and update can be written like this:
let line_counter = ref 0 in
while true; do
line_counter := !line_counter + 1
if !line_counter = 3 then
print .....
done;
To initialize a variable using a reference:
let var_name = ref value;
To dereference the value being refereed to by a variable:
!var_name
To update the value being refereed to by a variable:
var_name := !var_name + value