I am trying to understand and compile linear logic formalization in Coq: http://www.cs.nuim.ie/~jpower/Research/LinearLogic/ http://www.cs.nuim.ie/~jpower/Research/LinearLogic/ILL.v
Here is this code:
Inductive LinCons : (list ILinProp) -> ILinProp -> Prop :=
(* Structural Rules *)
Identity :
(A:ILinProp)
(`A |- A)
| Exchange :
(A,B,C : ILinProp)(D1,D2 : (list ILinProp))
((D1 ^ `A ^ `B ^ D2 |- C) -> (D1 ^ `B ^ `A ^ D2 |- C))
...
But this code does not compile, it is giving error message Syntax Error: Lexer: Undefined token for the code piece `A.
It is said in the accompanying article that ` simbol denotes the singleton list consisting from one element and that the ^ symbol if for the concatenation of the lists.
So - why the recent (CoqIDE 8.6.1) Coq does not recognize those symbols and should I import any addidional theories at the start of ILL.v file?
The syntax that file uses is defined in the moreLists file that is part of the development. However, that paper was written in 1999, and the version of Coq used there has very little to do with the current one. Sadly, it seems that you would need a lot of work to port that development to work now. For instance, back then Coq had a different set of basic tactics, a different standard library, and a different syntax extension mechanism.
Related
Here is a simple but very common grammar rule case in EBNF format, the Statements is a none terminal symbol and Statement is none terminal symbol:
Statements ::= (Statement ';')*
After converting this rule to NFA, and then do the subset contruction for converting the NFA to DFA, and at last get the dfa:
State0 -> Statement -> State1 -> ';' ->State0
State0 -> ε -> State0
The State0 is the DFA's start state representing the none terminal symbol Statements, also it is the finish state.
From State0 input Statement and traslate to State1 and input ';' at State1, translate to State0.
Also, State0 could translate to self with the ε.
And after converting the above dfa to regular grammar following the algorithm in dragon book, i get the following grammar rules:
Statements -> ε
Statements -> Statement Extend_NT
Extend_NT -> ';' Statements
It added the new none terminal symbol Extend_NT, but i want to get the following the regular grammars which does not contain the extend symbol Extend_NT:
Statements -> ε
Statements -> Statement ';' Statements
So the question is that is there any algorithm could get the above result that does not contain the new none terminal symbol Extend_NT?
Or it is just a engineering problem?
I'm not really sure I understand your question.
If you just have a single production for a non-terminal and that production just has a single repetition operator, either at the beginning or the end, you can apply a simple desugaring: (Here α and β are sequences of grammar symbols (but not EBNF symbols), and α might be empty.)
N ::= α (β)* ⇒ N → α | N β
N ::= (β)* α ⇒ N → α | β N
If α is empty, you could use either of the above. For an LALR(1) parser generator, the left-recursive version would be the usual choice; if you're building an LL parser, you will of course want the right-recursive version.
If there is more than one EBNF operator in the right-hand side, then you will need extra non-terminals, one for each EBNF repetition operator, except possibly one.
I don't know whether you'd call that an algorithm. I personally think of it as engineering, but the difference is not absolute.
I’ve been playing around with GADTs lately and was wondering if anybody could point me in the right direction for learning how to type this so it would compile, if it’s possible, or if I’m overly complicating things.
I have seen a few other answers to GADT pattern matching here but this seems to be a little different.
I’ve seen this type of thing done to represent a type with no possible values:
module Nothing = {
type t =
| Nothing(t);
};
So I wanted to use it to lock down this Exit.t type so I could have a type of Exit.t('a, Nothing.t) to represent the Success case, capturing the fact that there is no recoverable Failure value.
module Exit = {
type t('a, 'e) =
| Success('a): t('a, Nothing.t)
| Failure('e): t(Nothing.t, 'e);
This seemed to be okay, until I tried to write a flatMap function for it.
let flatMap: ('a => t('a1, 'e), t('a, 'e)) => t('a1, 'e) = (f, exit) =>
switch (exit) {
| Success(a) => f(a)
| Failure(_) as e => e
};
};
As is, it is inferring type Exit.t to always be Exit.t(Nothing.t, Nothing.t) which, I kind of understand since the type in the Failure case would set the first type to Nothing and the Success case would set the second type to Nothing.
I've tried the one thing I know, making some of those types local using type a. I've tried type a a1 e and type a e leaving 'a1 but I just don't seem to be able to capture the idea.
(I am using the OCaml syntax below, since the question is also tagged "ocaml", but the same should hold for Reason.)
First, your type Nothing.t is not empty. The cyclic value Nothing (Nothing (Nothing (...))) is a valid inhabitant. If you really want the type to be empty, do not put any constructor.
Second, as you guessed, in flat_map, your Failure branch forces 'a1 to be instantiated with Nothing.t. There is no way around that; it is not a deficiency of the compiler, just the only way to interpret this code.
Third, you are making things a bit too complicated, as Exit.t does not have to be a GADT in the first place, to achieve your goals.
Below is a simpler example that shows that, if Nothing.t is actually empty, then the compiler correctly allows irrelevant branches.
type nothing = |
type ('a, 'b) result =
| Success of 'a
| Failure of 'b
let only_success (x : ('a, nothing) result) : 'a =
match x with
| Success v -> v
| Failure _ -> . (* this branch can be removed, as it is correctly inferred *)
I am new to OCaml. I saw code like
let main_t = Term.(pure main $ address $ port $ pid_file $ log_file $ dbConf)
what does '$' symbol mean?
There's no predefined meaning in OCaml for $. It can be defined as an infix operator; the meaning must come from a library that you're using.
If I had to guess, I'd say that $ has been defined as a low precedence function application operator. It is used for this in Haskell, and it is often quite handy.
In OCaml it is possible to define your own infix and prefix operators. In cmdliner library the operator $ is defined as:
val ( $ ) : ('a -> 'b) t -> 'a t -> 'b t
(** [f $ v] is a term that evaluates to the result of applying
the evaluation of [v] to the one of [f]. *)
And is actually an infix form of the apply function (named app in Cmdliner). It is used to accumulate the arguments. Basically, a construct of the form pure f $a $b $c $d accepts a function f that takes four arguments of type a, b, c and d, given, that a is a value of type a Term.t, b is a value of type b Term.t, etc. In general this is a pattern for building typesafe variadic functions. For more information, about the pattern read the Applicative Programming with Effects paper.
there is no special meaning of $ in standard ocaml. In your case, this is coming from Term module where specific syntax may be defined. (BTW, which module is it ? - I mean how did you install it)
I am trying to write a small and simple parser for symbolic specifications in C++. I first tried using tools such as Yacc/Bison (which I already know) and ANTLR, but these are much too unwieldy and complex for what I am trying to do.
My language has the following binary operators: = (specification), + (sum), . (product); and the following unary operators: Seq (sequence of an expression), Z(###) (unit element which can be numbered), and E(###) (neutral element which can also be numbered). It should also contain variables. I think the binding priority on sum and product should be the standard priority.
Here is an example of a system of rules:
A = Seq B
B = Z(1) + Z(2).Z(2).C
C = E(1) + Z(4).Z(4).B
which I would like to parse to a associative map, indexing expression trees (Seq B) to a variable name (A).
After several auxiliary attempts (using Python, for instance), I have identified an ideal tool for this, Spirit in the Boost Library. I would like something more tightly integrated in the code. And the following StackOverflow gives most of the elements that I should need:
Boolean expression (grammar) parser in c++
However Spirit is pretty complicated, and I am not helped by the fact that I am not comfortable with the advanced C++ traits that the library uses - or more to the fact, I am not sure how to correct errors given by my compiler. My latest attempt:
https://gist.github.com/anonymous/354bb84e54042a3b54f3
It will not compile. Even if it did, I am not sure I understand how I would manipulate the parsed structure. I am not sure if I am on the right track.
Can somebody help get back on point? Or suggest an alternate reasonable solution?
UPDATE 1: Here is a more precise description of what I want.
A list of rules
"VAR = EXPR"
Where EXPR is:
EXPR := EXPR + EXPR
| EXPR . EXPR
| Seq EXPR
| Z<digits*> (defaults to zero if not placed)
| E<digits*> (defaults to zero if not placed)
| VAR
VAR := alnum+ (excludes Z## and E##)
For instance:
PP = Z + L1 . R1 + L2 . R2 + L3 . R3 + Seq Z3 . Seq Z4
L1 = Z10.Z9
R1 = Z12.PP + E4
...
Would give me an associative table:
[ "PP" -> parsing tree that I can navigate for (Z + L1...)
"L1" -> parsing tree for ...
]
Where PP is:
PP = (((((Z + (L1 . R1)) + (L2 . R2)) + (L3 . R3))) + ((Seq Z3) . (Seq Z4)))
I should say that cv_and_he's debugging was already incredibly useful, but:
-- I am not sure my grammar is correct;
-- I don't know how to parse the list from a system of equations;
-- I have no clue how to exploit/navigate the parsing tree once its been parsed.
My endgoal is to write recursive functions that traverse the tree and make some simulations accordingly.
UPDATE 2: I have managed to get most of the parsing done:
https://gist.github.com/anonymous/b6a63a1aa5caa6461dd6
I wonder if it is correct, or if I am missing a mistake. After that, what I cannot figure out is:
- how to best parse a list of such rules (instead of just one);
- how to traverse the parsed rules, and modify states (for instance, I would like to renumber the variables, and associate each variable with an integer that is always the same - lambda renumbering).
UPDATE 3: I guess part of my question now is: how can I make a "static visitor" not static, i.e., how can I make it have a state, that is modifiable.
UPDATE 4: I found an answer to the last question here:
How can I use the boost visitor concept with a class containing state variables?
I wonder if it is a sound solution. And I am still left wondering what is the best way of parsing a list of rules.
Can someone give a concise description of when the relaxed value restriction kicks in? I've had trouble finding a concise and clear description of the rules. There's Garrigue's paper:
http://caml.inria.fr/pub/papers/garrigue-value_restriction-fiwflp04.pdf
but it's a little dense. Anyone know of a pithier source?
An Addendum
Some good explanations were added below, but I was unable to find an explanation there for the following behavior:
# let _x = 3 in (fun () -> ref None);;
- : unit -> 'a option ref = <fun>
# let _x = ref 3 in (fun () -> ref None);;
- : unit -> '_a option ref = <fun>
Can anyone clarify the above? Why does the stray definition of a ref within the RHS of the enclosing let affect the heuristic.
I am not a type theorist, but here is my interpretation of Garrigue's explanation. You have a value V. Start with the type that would be assigned to V (in OCaml) under the usual value restriction. There will be some number (maybe 0) monomorphic type variables in the type. For each such variable that appears only in covariant position in the type (on the right sides of function arrows), you can replace it with a fully polymorphic type variable.
The argument goes as follows. Since your monomorphic variable is a variable, you can imagine replacing it with any single type. So you choose an uninhabited type U. Now since it is in covariant position only, U can in turn be replaced by any supertype. But every type is a supertype of an uninhabited type, hence it's safe to replace with a fully polymorphic variable.
So, the relaxed value restriction kicks in when you have (what would be) monomorphic variables that appear only in covariant positions.
(I hope I have this right. Certainly #gasche would do better, as octref suggests.)
Jeffrey provided the intuitive explanation of why the relaxation is correct. As to when it is useful, I think we can first reproduce the answer octref helpfully linked to:
You may safely ignore those subtleties until, someday, you hit a problem with an abstract type of yours that is not as polymorphic as you would like, and then you should remember than a covariance annotation in the signature may help.
We discussed this on reddit/ocaml a few months ago:
Consider the following code example:
module type S = sig
type 'a collection
val empty : unit -> 'a collection
end
module C : S = struct
type 'a collection =
| Nil
| Cons of 'a * 'a collection
let empty () = Nil
end
let test = C.empty ()
The type you get for test is '_a C.collection, instead of the 'a C.collection that you would expect. It is not a polymorphic type ('_a is a monomorphic inference variable that is not yet fully determined), and you won't be happy with it in most cases.
This is because C.empty () is not a value, so its type is not generalized (~ made polymorphic). To benefit from the relaxed value restriction, you have to mark the abstract type 'a collection covariant:
module type S = sig
type +'a collection
val empty : unit -> 'a collection
end
Of course this only happens because the module C is sealed with the signature S : module C : S = .... If the module C was not given an explicit signature, the type-system would infer the most general variance (here covariance) and one wouldn't notice that.
Programming against an abstract interface is often useful (when defining a functor, or enforcing a phantom type discipline, or writing modular programs) so this sort of situation definitely happens and it is then useful to know about the relaxed value restriction.
That's an example of when you need to be aware of it to get more polymorphism, because you set up an abstraction boundary (a module signature with an abstract type) and it doesn't work automatically, you have explicitly to say that the abstract type is covariant.
In most cases it happens without your notice, when you manipulate polymorphic data structures. [] # [] only has the polymorphic type 'a list thanks to the relaxation.
A concrete but more advanced example is Oleg's Ber-MetaOCaml, which uses a type ('cl, 'ty) code to represent quoted expressions which are built piecewise. 'ty represents the type of the result of the quoted code, and 'cl is a kind of phantom region variable that guarantees that, when it remains polymorphic, the scoping of variable in quoted code is correct. As this relies on polymorphism in situations where quoted expressions are built by composing other quoted expressions (so are generally not values), it basically would not work at all without the relaxed value restriction (it's a side remark in his excellent yet technical document on type inference).
The question why the two examples given in the addendum are typed differently has puzzled me for a couple of days. Here is what I found by digging into the OCaml compiler's code (disclaimer: I'm neither an expert on OCaml nor on the ML type system).
Recap
# let _x = 3 in (fun () -> ref None);; (* (1) *)
- : unit -> 'a option ref = <fun>
is given a polymorphic type (think ∀ α. unit → α option ref) while
# let _x = ref 3 in (fun () -> ref None);; (* (2) *)
- : unit -> '_a option ref = <fun>
is given a monomorphic type (think unit → α option ref, that is, the type variable α is not universally quantified).
Intuition
For the purposes of type checking, the OCaml compiler sees no difference between example (2) and
# let r = ref None in (fun () -> r);; (* (3) *)
- : unit -> '_a option ref = <fun>
since it doesn't look into the body of the let to see if the bound variable is actually used (as one might expect). But (3) clearly must be given a monomorphic type, otherwise a polymorphically typed reference cell could escape, potentially leading to unsound behaviour like memory corruption.
Expansiveness
To understand why (1) and (2) are typed the way they are, let's have a look at how the OCaml compiler actually checks whether a let expression is a value (i.e. "nonexpansive") or not (see is_nonexpansive):
let rec is_nonexpansive exp =
match exp.exp_desc with
(* ... *)
| Texp_let(rec_flag, pat_exp_list, body) ->
List.for_all (fun vb -> is_nonexpansive vb.vb_expr) pat_exp_list &&
is_nonexpansive body
| (* ... *)
So a let-expression is a value if both its body and all the bound variables are values.
In both examples given in the addendum, the body is fun () -> ref None, which is a function and hence a value. The difference between the two pieces of code is that 3 is a value while ref 3 is not. Therefore OCaml considers the first let a value but not the second.
Typing
Again looking at the code of the OCaml compiler, we can see that whether an expression is considered expansive determines how the type of the let-expressions is generalised (see type_expression):
(* Typing of toplevel expressions *)
let type_expression env sexp =
(* ... *)
let exp = type_exp env sexp in
(* ... *)
if is_nonexpansive exp then generalize exp.exp_type
else generalize_expansive env exp.exp_type;
(* ... *)
Since let _x = 3 in (fun () -> ref None) is nonexpansive, it is typed using generalize which gives it a polymorphic type. let _x = ref 3 in (fun () -> ref None), on the other hand, is typed via generalize_expansive, giving it a monomorphic type.
That's as far as I got. If you want to dig even deeper, reading Oleg Kiselyov's Efficient and Insightful Generalization alongside generalize and generalize_expansive may be a good start.
Many thanks to Leo White from OCaml Labs Cambridge for encouraging me to start digging!
Although I'm not very familiar with this theory, I have asked a question about it.
gasche provided me with a concise explanation. The example is just a part of OCaml's map module. Check it out!
Maybe he will be able to provide you with a better answer. #gasche