So, I have a Rodin event-b project and would like to define a known static relation. For examples sake, lets say I have a set {a,b,c} and would like to specify the relation constant which is equal to {(a,1),(a,2),(b,3)} in an context axiom. (May be multilined, but preferably single if feasable)
How would I go about this?
CONTEXT
example
SETS
list
CONSTANTS
a
b
c
relation
AXIOMS
axm1 : partition(list, {a}, {b}, {c})
axm2 : relation ∈ list↔1‥5
axm3 : ???
END
axm3: relation = {a↦1, a↦2, b↦3}
Related
Currently, I have within the same OCaml file,
blah.ml:
module type blah =
sig
val a : some-type
end
module type X =
sig
val x : some-type
end
module Y : X =
struct
let x = some-def
end
module Z : X =
struct
let x = some-other-def
end
blah.mli looks like this:
module type blah =
sig
val a
end
module type X =
sig
val x : some-type
end
module Y : X
module Z : X
I want X, Y, and Z to be in separate files with separate interfaces. How do I tell in Y.mli and Z.mli that Y and Z have type X?
Any readings for this would also be appreciated. There are a lot of resources talking about modules, interfaces, and functors, but they don't mention interface files for modules that have other modules as types.
You can create x.ml containing the sig, y.ml containing the module, and z.ml containing that module. You don't need to do anything special to tell the compiler that Y : X and Z : X. The compiler infers the module type automatically from the fact that the module conforms to the type i.e. it implements every binding that the module type needs. If Y or Z don't conform, the type error will be shown at the point of use.
If you want to restrict the module type at the point of definition that's also doable, by giving each module an interface file and includeing the required signature there. For example:
(* x.ml *)
module type S = sig
val x : some-type
end
(* y.mli *)
include X.S
(* y.ml *)
let x = some-def
...and so on.
However this often becomes too restrictive as the signature hides too much detail about the types. So in reality you may actually need to add type equality sharing constraints to avoid compile errors where you want to expose more type info. E.g.:
(* y.mli *)
include X.S with type t = int
Often it is easier to not have the explicit interface file at all unless you really need to make some parts of the module private.
The following code gives me an error:
Require Import Reals.
Require Import List.
Import ListNotations.
Open Scope R_scope.
Definition C := (R * R)%type.
Definition RtoC (r : R) : C := (r,0).
Coercion RtoC : R >-> C.
Definition lC : list C := [0;0;0;1].
Error: The term "[0; 0; 0; 1]" has type "list R" while it is expected to have type "list C".
But I've defined RtoC as a coercion and I don't see any problems when I use
Definition myC : C := 4.
How do I get Coq to apply the coercion within the list?
Related question: If I enter Check [0;0;0;1] it returns list R, inserting an implicit IZR before every number. Why does Coq think I want Rs rather than Zs?
I'm unsure there is a fully satisfying solution to your question.
Indeed, as recalled in the Coq refman:
Given a term, possibly not typable, we are interested in the problem of determining if it can be well typed modulo insertion of appropriate coercions.
and it turns out that in your example, the term [0;0;0;1] itself is typable as a list R and it is type-checked "in one go"; thereby when the [0;0;0;1] : list C type mismatch occurs, as there's no "backtracking", a coercion can't be inserted within the list elements.
So maybe you could adapt your formalization in a different way, or just use one of these workarounds:
Rewriting your term into a β-redex:
Definition lC := (fun z o => [z;z;z;o] : list C) 0 1.
Or inserting a few more typecasts around each element:
Definition lC := [0:C; 0:C; 0:C; 1:C].
Regarding your last question
Why does Coq think I want Rs rather than Zs?
this comes from your line Open Scope R_scope., which implies numeral litterals are recognized by default as belonging to R (which deals with the classical axiomatization of the real numbers formalized in the standard library Reals). More specifically, the implementation has changed in Coq 8.7, as from coq/coq#a4a76c2 (discussed in PR coq/coq#415). To sum up, a literal such as 5%R is now parsed as IZR 5, that is, IZR (Zpos (xI (xO xH))), while it used to be parsed to a much less concise term in Coq 8.6:
Rplus R1 (Rmult (Rplus R1 R1) (Rplus R1 R1)).
I'm trying to define an entity named isVector using the following syntax
Require Export Setoid.
Require Export Coq.Reals.Reals.
Require Export ArithRing.
Definition Point := Type.
Record MassPoint:Type:= cons{number : R ; point: Point}.
Variable add_MP : MassPoint -> MassPoint -> MassPoint .
Variable mult_MP : R -> MassPoint -> MassPoint .
Variable orthogonalProjection : Point -> Point -> Point -> Point.
Definition isVector (v:MassPoint):= exists A, B :Point , v= add_MP((−1)A)(1B).
And the Coq IDE keeps complaining that there's a syntax error for the definition. Currently, I haven't figured it out.
There are many problems here.
First, you'd write:
exists A B : Point, …
with no comma between the different variables.
But then, you also have syntax errors on the right-hand side. First, I'm not sure those 1 and -1 operations exist. Second, function calls would be written this way:
add_MP A B
You can write them the way you do:
add_MP(A)(B)
But in the long run you should probably become used to the syntax of function calls being just a whitespace! You might need to axiomatize this -1 operation the way you axiomatized other operations, unless they are a notation that you defined somewhere but did not post here.
Thanks for the help.
After experimenting a little bit. Below is the solution that works.
Definition Point:= Type.
Record massPoint: Type := cons{number: R; point: Point}.
Variable add_MP: massPoint -> massPoint -> massPoint.
Variable mult_MP: R -> massPoint -> massPoint.
Definition tp (p:Point) := cons (-1) p.
Definition isVector(v:massPoint):= exists A B : Point, v = add_MP(cons (-1) A)(cons 1 B).
DECLARE A,B;
DECLARE Annotation C(Annotation firstA, Annotation secondA,...);
"token1|token2|...|tokenn" -> A;
"token3|token4" -> B;
A A B {->MARK(C,1,3)};
I did with GATHER
(A COMMA A B) {-> GATHER(C,1,4,"firstA"=1,"secondA" = 3,"B"=4)};
But how about in case of unknown sequence of A type? as below, how can it be possible to store all A in features? The number of features are also unknown. In plan java, we declare String array and can add element, but in Ruta seems to be no as such process.
(A (COMMA A)+ B) {-PARTOF(C) -> GATHER(C,beginPosition,endPosition,"firstA"=1,"secondA" = 3,"thirdA"=?,so on)};
Annotations in UIMA refer to the complete span, from the begin offset to the end offset. So, if you want to specify something with two elements, then a simple annotation is not sufficient. You cannot create an annotation of the type C that covers the first A and the B but not the second A.
However, you can store the important information in feature values. How to implement it depends on various things.
If there are always exactly two annotation you want to remember, then add two features to type C and assign the feature values in the given rule, e.g., by CREATE(C,1,3,"first" = A, "second" = B ).
You can also use different actions like GATHER, or use one FSArray feature in order to store the annotations.
A complete example with a FSArray:
DECLARE A, B;
DECLARE Annotation C (FSArray as, B b);
"A" -> A;
"B" -> B;
(A (COMMA A)+ B){-PARTOF(C) -> CREATE(C, "as" = A, "b" = B)};
If applied on a text like "A, A, A B", the last rule creates one annotation of type C that stores three A annotations in the feature "as" and one B annotation in the feature "b"
I'd like my own scope, to play around with long distfixes.
Declare Scope my_scope.
Delimit Scope my_scope with my.
Open Scope my_scope.
Definition f (x y a b : nat) : nat := x+y+a+b.
Notation "x < y * a = b" := (f x y a b)
(at level 100, no associativity) : my_scope.
Check (1 < 2 * 3 = 4)%my.
How do you make a new scope?
EDIT: I chose "x < y * a = b" to override Coq's operators (each with a different precedence).
The command Declare Scope does not exist. The various commands about scopes are described in section 12.2 of the Coq manual.
Your choice of an example notation has inherent problems, because it clashes with pre-defined notations, which seem to be used before your notation.
When looking at the first components the parser sees _ < _ and thinks that you are actually talking about comparison of integers, then it sees the second part as being an instance of the notation _ * _, then it sees that all that is the left hand side of an equality. And all along the parser is happy, it constructs an expression of the form:
(1 < (2 * 3)) = 4
This is constructed by the parser, and the type system has not been solicited yet. The type checker sees a natural number as the first child of (_ < _) and is happy. It sees (_ * _) as the second child and it is happy, it now knows that the first child of that product should be a nat number and it is still happy; in the end it has an equality, and the first component of this equality is in type Prop, but the second component is in type nat.
If you type Locate "_ < _ * _ = _". the answer tells you that you did define a new notation. The problem is that this notation never gets used, because the parser always finds another notation it can use before. Understanding why a notation is preferred to another one requires more knowledge of parsing technology, as alluded to in Coq's manual, chapter 12, in the sentence (obscure to me):
Coq extensible parsing is performed by Camlp5 which is essentially a LL1 parser.
You have to choose the levels of the various variables, x, y, a, and b so that none of these variables will be able to match too much of the text. For instance, I tried defining a notation close to yours, but with a starting and an ending bracket (and I guess this simplifies the task greatly).
Notation "<< x < y * a = b >>" := (f x y a b)
(x at level 59, y at level 39, a at level 59) : my_scope.
The level of x is chosen to be lower than the level of =, the level of y is chosen to be lower than the level of *, the level of a is chosen to be lower than =. The levels were obtained by reading the answer of the command Print Grammar constr. It seems to work, as the following command is accepted.
Check << 1 < 2 * 3 = 4 >>.
But you may need to include a little more engineering to have a really good notation.
To answer the actual question in your title:
The new scope gets created when you declare a notation that uses it. That is, you don’t declare a new scope my_scope separately. You just write
Notation "x <<< y" := (f x y) (at level 100, no associativity) : my_scope.
and that declares a new scope my_scope.
The answers for this question only apply to older versions of Coq. I'm not sure when it started but in at least Coq 8.13.2, Coq prefers the user to first use Declare Scope create a new scope. What the OP has in their code is Coq's preferred way to declare scopes now.
See the current manual