I'm trying to use 32-bit integers in a Why3 specification of a Simulink model, and I've found the mach.int library, that is, at least in one place, described as being part of the standard library. However, when I try to use it with the following importing command:
use import mach.int.Int32
I get the message:
Library file not found: mach.int
This is my first library with a "." in it, so I'm not sure if my syntax is wrong, or this library isn't actually part of the standard library, or if I'm doing something else wrong.
What is the proper way to use the mach.int.Int32 module?
Additional detail
My why3 version is 0.87.3:
▶ why3 --version
Why3 platform, version 0.87.3
I looked in my ~/.why3.conf file and found these lines:
[main]
loadpath = "/opt/gps/share/why3/theories"
loadpath = "/opt/gps/share/why3/modules"
loadpath = "/opt/gps/share/spark/theories"
I looked in /opt/gps/share/why3/modules (and /opt/gps/share/why3/theories and /opt/gps/share/spark/theories) and found no mach.int.*, so I created a mach.int.mlw file in /opt/gps/share/why3/modules, and made sure that why3 was OK with it:
▶ why3 prove -P z3 mach.int.mlw
mach.int.mlw Int WP_parameter infix / : Valid (0.01s)
mach.int.mlw Int WP_parameter infix % : Valid (0.01s)
mach.int.mlw Refint63 WP_parameter incr : Valid (0.02s)
mach.int.mlw Refint63 WP_parameter decr : Valid (0.02s)
mach.int.mlw Refint63 WP_parameter infix += : Valid (0.02s)
mach.int.mlw Refint63 WP_parameter infix -= : Valid (0.02s)
mach.int.mlw Refint63 WP_parameter infix *= : Valid (0.02s)
mach.int.mlw MinMax63 WP_parameter min : Valid (0.01s)
mach.int.mlw MinMax63 WP_parameter max : Valid (0.02s)
The result is the same.
It turns out that why3 was looking for mach.int.Int32 in a module int.mlw in a mach subdirectory.
Putting the mach.int library in the /opt/gps/share/why3/modules/mach/ directory solves the problem with the library not being found (where /opt/gps/share/why3/modules is defined as part of loadpath in my ~/.why3.conf file).
Related
I have a module MyMonad that provides a bind function as (let*) operator, but also as >>= operator for old-style code.
The idea is that old code can use it as:
let foobar () =
let open MyMonad in
foo "test" >>= fun s ->
bar s 1 >>= fun (a, b) ->
return a + b
and that new code compiled on OCaml >= 4.08 can use it as:
let foobar () =
let open MyMonad in
let* s = foo "test" in
let* a, b = bar s 1 in
return a + b
Inside the module MyMonad.ml, these operators are implemented in a straight forward way:
let (>>=) a f =
...
let (let*) = (>>=)
However, on OCaml <= 4.07, the last line is a syntax error. And the same is true for the val (let*) : ... line in the MyMonad.mli interface file.
This issue occurs especially when this module is meant to be used in BuckleScript (nowadays ReScript) as well, which is based on OCaml 4.06 and where it is not clear when they will upgrade to a later OCaml version.
How can I mark those last lines to be compiled only on OCaml >= 4.08?
Note: I'm aware that I could create two modules, one adding (let*) on top of the other and being excluded on old compilers. But I wonder if there is a more elegant solution.
To answer this question myself, there is indeed to need to stick with >>=, the new syntax can be used via shims with old OCaml compilers and even BuckleScript (nowadays ReScript).
The latter can be achieved as follows:
Create a new OPAM switch into the current directory for the 4.06 OCaml compiler. This is the version on which is the current BuckleScript version is based, and it is needed to convince the shims to actually do something (for more recent compiler versions those would compile to a no-op):
opam switch create -wy --no-install . 4.06.0
Install the ocaml-syntax-shims OPAM package:
opam install -wy ocaml-syntax-shims
Add the following preprocessing line to you bsconfig.json configuration file:
{
"pp-flags": "./_opam/bin/ocaml-syntax-shims -dump-ast",
...
}
Many of the additions to the language or stdlib are followed by backporting libraries usually called *-shims.
For your problem, there is
https://github.com/ocaml-ppx/ocaml-syntax-shims
I'm trying to use the PiGPIO library with Kotlin Native as a linked library (not using the deamon).
So I'm using C interop with a .def file that references the pigpio.h file.
It works (I managed to get a LED blinking) but there is an issue with the typing of integers.
Althoug I didn't enable the experimental unsigned integers feature, the generated stubs are using type UInt.
For example for the parameters of this function:
#kotlinx.cinterop.internal.CCall public external fun gpioSetMode(gpio: kotlin.UInt, mode: kotlin.UInt): kotlin.Int { /* compiled code */ }
That's OK with me as they are of type unsigned in C and I want this to be as type-safe as possible:
int gpioSetMode(unsigned gpio, unsigned mode);
Now the problem is that the values to be used as parameters for the functions are defined using macro definitions in the .h file. For example for the mode parameter:
#define PI_INPUT 0
#define PI_OUTPUT 1
The generated Kotlin constants corresponding to those values are of type Int:
public const val PI_INPUT: kotlin.Int /* compiled code */
public const val PI_OUTPUT: kotlin.Int /* compiled code */
However, although calling the function with the constant as a parameter is possible:
gpioSetMode(14, PI_OUTPUT) // compiles fine
I can't create a method that takes the mode as a parameter and use it:
fun main() {
setMode(PI_OUTPUT) // fails to compile (Type Mismatch)
}
fun setMode(mode : UInt) {
gpioSetMode(14, mode)
}
Is there a way to force all constants of positive integers to be of type UInt ?
AFAIK, there is no such option in the cinterop tool. In fact, one can say that the problem grows from the library header not using unsigned literals in it's "define" section. But it can be omitted in C, so this header is fine. The tool here is a bit nerdier, so it assumes all integer literals with no additional suffix as the signed typed. About the way that your generated function works. In Kotlin, there is a smart cast concept(see here), but here it is a problem. In this documentation part, there is a note on smart-casting availability only for checks inside a module. In your case, gpioSetMode(gpio, mode) and PI_OUTPUT are located in the same module, while your setMode is in another one.That's why the first call compiles and the second one does not. I managed to workaround it in my small sample like that: just added into my code this like, redefining the constant
import my.*
const val PI_OUTPUT = my.PI_OUTPUT
where my is the library package, most probably pigpio for you. After that, smart casts will be available for the library functions, and all functions you declare in this module.
I would like to have my own implementation of an existing module but to keep a compatible interface with the existing module. I don't have a module type for the existing module, only an interface. So I can't use include Original_module in my interface. Is there a way to get a module type from an interface?
An example could be with the List module from the stdlib. I create a My_list module with exactly the same signature than List. I could copy list.mli to my_list.mli, but it does not seem very nice.
In some cases, you should use
include module type of struct include M end (* I call it OCaml keyword mantra *)
rather than
include module type of M
since the latter drops the equalities of data types with their originals defined in M.
The difference can be observed by ocamlc -i xxx.mli:
include module type of struct include Complex end
has the following type definition:
type t = Complex.t = { re : float; im : float; }
which means t is an alias of the original Complex.t.
On the other hand,
include module type of Complex
has
type t = { re : float; im : float; }
Without the relation with Complex.t, it becomes a different type from Complex.t: you cannot mix code using the original module and your extended version without the include hack. This is not what you want usually.
You can look at RWO : if you want to include the type of a module (like List.mli) in another mli file :
include (module type of List)
For the question and the grammar suggested by #BartKiers (Thank you!), I added the options block to specify the output to be
options{
language=Java;
output=AST;
ASTLabelType=CommonTree;
}
However, I am not able to figure out how to access the output i.e. AST. I need to traverse through the tree and process each operation that was specified in the input.
Using your example here, I am trying to implement rules returning values. However, I am running into following errors:
relational returns [String val]
: STRINGVALUE ((operator)^ term)?
{val = $STRINGVALUE.text + $operator.text + $term.text; }
;
term returns [String rhsOperand]
: QUOTEDSTRINGVALUE {rhsOperand = $QUOTEDSTRINGVALUE.text;}
| NUMBERVALUE {rhsOperand = $NUMBERVALUE.text; }
| '(' condition ')'
;
Compilation Error:
Checking Grammar RuleGrammarParser.g...
\output\RuleGrammarParser.java:495: cannot find symbol
symbol : variable val
location: class RuleGrammarParser
val = (STRINGVALUE7!=null?STRINGVALUE7.getText():null) + (operator8!=null?input.toString(operator8.start,operator8.stop):null) + (term9!=null?input.toString(term9.start,term9.stop):null);
^
\output\RuleGrammarParser.java:612: cannot find symbol
symbol : variable rhsOperand
location: class RuleGrammarParser
rhsOperand = (QUOTEDSTRINGVALUE10!=null?QUOTEDSTRINGVALUE10.getText():null);
^
\output\RuleGrammarParser.java:632: cannot find symbol
symbol : variable rhsOperand
location: class RuleGrammarParser
rhsOperand = (NUMBERVALUE11!=null?NUMBERVALUE11.getText():null);
^
3 errors
Can you please help me understand why this fails to compiler?
Added the pastebin: http://pastebin.com/u1Bv3L0A
By simply adding output=AST to the options section you don't create a AST, but a flat, 1 dimensional list of tokens. To mark certain tokens as root (or children), you need to do a bit of work.
Checkout this answer which explains how to create a proper AST and get access to the tree the parser then produces (the CommonTree tree in the main method of the answer I mentioned).
Note that you can safely remove language=Java;: by default the target language is Java (no harm in leaving it there though).
In OCaml 3.11, I want to "extend" an existing module using the include directive, like so:
module MyString = struct
include String
let trim s = ...
end
No problem. But now I want to expose this module's type explicitly (i.e. in a .mli file). I want something like this:
module MyString : sig
include String
val trim : string -> string
end
But the include syntax is not correct because String refers to a module, not a module type (and the compiler does indeed barf). How can I refer to the module type for String here (without having write it out explicitly in a sig expression)?
Thanks!
OCaml 3.12 will have a construct like module type of M that I believe would have solved your problem. Meanwhile, you can have the compiler generate the lengthy signature with ocamlc -i. Sorry, but I think it's the best you can do with 3.11.