I would like to write a module that exports a predicate where the user should be able to access a predicate p/1 as a prefix operator. I have defined the following module:
:- module(lala, [p/1]).
:- op(500, fy, [p]).
p(comment).
p(ca).
p(va).
and load it now via:
?- use_module(lala).
true.
Unfortunately, a query fails:
?- p X.
ERROR: Syntax error: Operator expected
ERROR: p
ERROR: ** here **
ERROR: X .
After setting the operator precedence properly, everything works:
?- op(500, fy, [p]).
true.
?- p X.
X = comment ;
X = ca ;
X = va.
I used SWI Prolog for my output but the same problem occurs in YAP as well (GNU Prolog does not support modules). Is there a way the user does not need to set the precedence themselves?
You can export the operator with the module/2 directive.
For example:
:- module(lala, [p/1,
op(500, fy, p)]).
Since the operator is then also available in the module, you can write for example:
p comment.
p ça.
p va.
where p is used as a prefix operator.
Related
Please help.
I'm encounter this compilation error in GNU prolog, when I use SWISH it looks like code compile but when I try to
?- current_room(X). it shows me error anyway (just false), so I expect something is not right with way I defined dynamic.
% Rooms
:- dynamic current_room/1.
room(kitchen).
room(hall).
room(living_room).
room(dinning).
path(kitchen,dinning,n).
path(kitchen,hall2,e).
path(hall,living_room,s).
path(living_room,hall,n).
path(living_room,hall2,s).
path(living_room,dinning,w).
path(dinning,living_room,e).
path(dinning,kitchen,s).
path(hall2,living_room,n).
path(hall2,pantry,s).
path(pantry,hall2,n).
objects(couch).
in_room(living_room,couch).
route(room).
%(current_room,Destination, X).
%asserta(current_room(Destination)).
move(X) :- current_room(Z), path(Z,Y,X), retractall(my_pos(Z)), assert(my_pos(Y)).
n :- move(n).
s :- move(s).
w :- move(w).
e :- move(e).
start :- write('Type n/s/e/w'),nl, asserta(current_room(hall2)).
GNU prolog have different syntax :- dynamic(current_room/1)..
Going at the root of Agda standard library, and issuing the following command:
grep -r "module _" . | wc -l
Yields the following result:
843
Whenever I encounter such anonymous modules (I assume that's what they are called), I quite cannot figure out what their purpose is, despite of their apparent ubiquity, nor how to use them because, by definition, I can't access their content using their name, although I assume this should be possible, otherwise their would be no point in even allowing them to be defined.
The wiki page:
https://agda.readthedocs.io/en/v2.6.1/language/module-system.html#anonymous-modules
has a section called "anonymous modules" which is in fact empty.
Could somebody explain what the purpose of anonymous modules is ?
If possible, any example to emphasize the relevance of the definition of such modules, as well as how to use their content would be very much appreciated.
Here are the possible ideas I've come up with, but none of them seems completely satisfying:
They are a way to regroup thematically identical definitions inside an Agda file.
Their name is somehow infered by Agda when using the functions they provide.
Their content is only meant to be visible / used inside their englobing module (a bit like a private block).
Anonymous modules can be used to simplify a group of definitions which share some arguments. Example:
open import Data.Empty
open import Data.Nat
<⇒¬≥ : ∀ {n m} → n < m → n ≥ m → ⊥
<⇒¬≥ = {!!}
<⇒> : ∀ {n m} → n < m → m > n
<⇒> = {!!}
module _ {n m} (p : n < m) where
<⇒¬≥′ : n ≥ m → ⊥
<⇒¬≥′ = {!!}
<⇒>′ : m > n
<⇒>′ = {!!}
Afaik this is the only use of anonymous modules. When the module _ scope is closed, you can't refer to the module anymore, but you can refer to its definitions as if they hadn't been defined in a module at all (but with extra arguments instead).
I am trying to run following very simple code:
open Str
print (Str.first_chars "testing" 0)
However, it is giving following error:
$ ocaml testing2.ml
File "testing2.ml", line 2, characters 0-5:
Error: Syntax error
There are no further details in the error message.
Same error with print_endline also; or even if no print command is there. Hence, the error is in part: Str.first_chars "testing" 0
Documentation about above function from here is as follows:
val first_chars : string -> int -> string
first_chars s n returns the first n characters of s. This is the same
function as Str.string_before.
Adding ; or ;; at end of second statement does not make any difference.
What is the correct syntax for above code.
Edit:
With following code as suggested by #EvgeniiLepikhin:
open Str
let () =
print_endline (Str.first_chars "testing" 0)
Error is:
File "testing2.ml", line 1:
Error: Reference to undefined global `Str'
And with this code:
open Str;;
print_endline (Str.first_chars "testing" 0)
Error is:
File "testing2.ml", line 1:
Error: Reference to undefined global `Str'
With just print command (instead of print_endline) in above code, the error is:
File "testing2.ml", line 2, characters 0-5:
Error: Unbound value print
Note, my Ocaml version is:
$ ocaml -version
The OCaml toplevel, version 4.02.3
I think Str should be built-in, since opam is not finding it:
$ opam install Str
[ERROR] No package named Str found.
I also tried following code as suggested in comments by #glennsl:
#use "topfind"
#require "str"
print (Str.first_chars "testing" 0)
But this also give same simple syntax error.
An OCaml program is a list of definitions, which are evaluated in order. You can define values, modules, classes, exceptions, as well as types, module types, class types. But let's focus on values so far.
In OCaml, there are no statements, commands, or instructions. It is a functional programming language, where everything is an expression, and when an expression is evaluated it produces a value. The value could be bound to a variable so that it could be referenced later.
The print_endline function takes a value of type string, outputs it to the standard output channel and returns a value of type unit. Type unit has only one value called unit, which could be constructed using the () expression. For example, print_endline "hello, world" is an expression that produces this value. We can't just throw an expression in a file and hope that it will be compiled, as an expression is not a definition. The definition syntax is simple,
let <pattern> = <expr>
where is either a variable or a data constructor, which will match with the structure of the value that is produced by <expr> and possibly bind variable, that are occurring in the pattern, e.g., the following are definitions
let x = 7 * 8
let 4 = 2 * 2
let [x; y; z] = [1; 2; 3]
let (hello, world) = "hello", "world"
let () = print_endline "hello, world"
You may notice, that the result of the print_endline "hello, world" expression is not bound to any variable, but instead is matched with the unit value (), which could be seen (and indeed looks like) an empty tuple. You can write also
let x = print_endline "hello, world"
or even
let _ = print_endline "hello, world"
But it is always better to be explicit on the left-hand side of a definition in what you're expecting.
So, now the well-formed program of ours should look like this
open Str
let () =
print_endline (Str.first_chars "testing" 0)
We will use ocamlbuild to compile and run our program. The str module is not a part of the standard library so we have to tell ocamlbuild that we're going to use it. We need to create a new folder and put our program into a file named example.ml, then we can compile it using the following command
ocamlbuild -pkg str example.native --
The ocamlbuild tool will infer from the suffix native what is your goal (in this case it is to build a native code application). The -- means run the built application as soon as it is compiled. The above program will print nothing, of course, here is an example of a program that will print some greeting message, before printing the first zero characters of the testing string,
open Str
let () =
print_endline "The first 0 chars of 'testing' are:";
print_endline (Str.first_chars "testing" 0)
and here is how it works
$ ocamlbuild -package str example.native --
Finished, 4 targets (4 cached) in 00:00:00.
The first 0 chars of 'testing' are:
Also, instead of compiling your program and running the resulting application, you can interpret your the example.ml file directly, using the ocaml toplevel tool, which provides an interactive interpreter. You still need to load the str library into the toplevel, as it is not a part of the standard library which is pre-linked in it, here is the correct invocation
ocaml str.cma example.ml
You should add ;; after "open Str":
open Str;;
print (Str.first_chars "testing" 0)
Another option is to declare code block:
open Str
let () =
print (Str.first_chars "testing" 0)
I'd like to create a function with type constrained by an interface. My intention is to build a simple monoid solver using VerifiedMonoid defined inClasses.Verified module from contrib package.
Idris gives me the following error:
Monoid-prover.idr line 29 col 5:
When checking type of MonoidProver.eval:
Can't find implementation for VerifiedMonoid a
for the type signature of eval:
eval : VerifiedMonoid a => Expr n -> Env a n -> a
Am I doing something silly or missing something? Such constrained types (like eval's type) can be interpreted like Haskell's types?
The complete code is shown below.
module MonoidProver
import Classes.Verified
import Data.Fin
import Data.Vect
%default total
infixl 5 :+:
data Expr : Nat -> Type where
Var : Fin n -> Expr n
Id : Expr n
(:+:) : Expr n -> Expr n -> Expr n
Env : VerifiedMonoid a => (a : Type) -> Nat -> Type
Env a n = Vect n a
eval : VerifiedMonoid a => Expr n -> Env a n -> a
eval (Var i) env = index i env
eval Id env = neutral
eval (e :+: e') env = eval e env <+> eval e' env
As #Cactus mentioned in a comment, the problem here is that the type signature for Env is not correct. Specifically, since the constraint is on the value of the argument, it is a dependent (pi) type, and Idris enforces that dependent types go left-to-right (be introduced before they are used). My understanding is that basically the compiler will see the argument x : a as being shorthand for , where is the part of the type signature to the right of the quantifier. This means that (a : Type) actually binds a fresh a, which is not the same a that was used in the VerifiedMonoid a constraint (which is implicitly universally bound).
Luckily, since Idris isn't Haskell (where all type class constraints must be at the head of the type signature), this is easy to fix: just change your type signature to Env : (a : Type) -> VerifiedMonoid a => Nat -> Type, so that a is bound before it is used!
I figured that I can do it on the command line REPL like so:
java -jar frege-repl-1.0.3-SNAPSHOT.jar -hints -warnings
But how can I do the same in http://try.frege-lang.org
Hints and warnings are already enabled by default. For example,
frege> f x = f x
function f :: α -> β
3: application of f will diverge.
Perhaps we can make it better by explicitly saying it as warning or hint (instead of colors distinguishing them) something like:
[Warning] 3: application of f will diverge.
and providing an option to turn them on/off.
Update:
There was indeed an issue (Thanks Ingo for pointing that out!) with showing warnings that are generated in a later phase during the compilation. This issue has been fixed and the following examples now correctly display warnings in the REPL:
frege> h x = 0; h false = 42
function h :: Bool -> Int
4: equation or case alternative cannot be reached.
frege> f false = 6
function f :: Bool -> Int
5: function pattern is refutable, consider
adding a case for true