Consider the following BNF grammar (BNF, Recursion) - recursion

Write a BNF grammar for recognizing all sentences in the form of anbn-2, where n>1. For example, aa, aaab, aaaabb are all accepted, but abbb, aab, aabb are not (Hint: use recursion).
This is my derivation:
S ::= AZ
Z ::= A | AAB
A ::= a
B ::= b
Is this correct?
EDIT: Maybe this is correct?
S -> a | X | Y X-> aX | a Y -> aX | b

Both are completely incorrect.
First grammar: since A turns only to a, and B only to b, we can replace A by a and B by b. The grammar will be:
S -> aZ
Z -> a
Z -> aab
Thus, S turns to either aa or aaab, but not, for example, aaaabb.
Second grammar: use the first rule and turn S to a. Since a is not a valid word, the grammar is also incorrect. (Alternatively, we could turn S to X, then X to aX 9 times, then X to a, making aaaaaaaaaa, which is also invalid).

Your first grammar only produces:
S -> AZ -> aZ -> aa
S -> AZ -> aZ -> aAAB -> aaab
Your second grammar allows words containing only a's, which are not part of the language. For instance:
S -> a
I'd simply start with two a's and then produce arbitrary pairs. Hence, the grammar looks like (BNF syntax):
<term> ::= "aa" | "aa" <pair>
<pair> ::= "ab" | "a" <pair> "b"
Example:
<term> -> "aa"
<term> -> "aa" <pair> -> "aaab"
<term> -> "aa" <pair> -> "aaa" <pair> "b" -> "aaaabb"
...

Related

Comparison in pattern matching in OCaml

I want to write a function set which changes the index i in the 'a array a to the value 'a v and raise an invalid_argument exception if i is bigger then the length-1 of the array.
I know that this can be done with if/then/else:
let set i v a =
let l = Array.length a in
if i > (l-1) then
raise (Invalid_argument "index out of bounds")
else
a.(i) <- v
However I want to know if this can be achieved in a pure functional approach, using pattern matching and the OCaml standard library. I don't how to compare values inside the pattern matching, I get an error at the marked line:
let set i v a =
let l = Array.length a in
match i with
>>>>>> | > l-1 -> raise (Invalid_argument "index out of bounds")
| _ -> a.(i) <- v
Is there a workaround to achieve this? perhaps with a helper function?
An if expression is a pure functional approach, and is also the right approach. In general, pattern matching has the purpose of deconstructing values; it's not an alternative to an if.
However, it's still possible to do this with pattern matching:
let set i v a =
let l = Array.length a in
match compare l i with
| 1 -> a.(i) <- v
| _ -> raise ## Invalid_argument "index out of bounds"
EDIT: Apparently, compare can return other values than -1, 0 and 1 so this version is not reliable (but you wouldn't use it anyway, would you?)...
Or, more efficiently
let set i v a =
let l = Array.length a in
match l > i with
| true -> a.(i) <- v
| false -> raise ## Invalid_argument "index out of bounds"
But then you realize that matching over a boolean is just an if. Which is why the correct version is still
let set i v a =
let l = Array.length a in
if l > i then a.(i) <- v
else raise ## Invalid_argument "index out of bounds"
BlackBeans' answer is correct. But also know that pattern-matching in OCaml can take advantage of conditional guards when you want to place a conditional on a pattern.
Consider the following simple example.
type species = Dog | Cat
type weight = int
type pet = Pet of species * weight
let sound = function
| Pet (Dog, weight) when weight < 10 -> "Yip!"
| Pet (Dog, _) -> "Woof!"
| Pet (Cat, weight) when weight > 100 -> "ROAR!!!"
| _ -> "Meow!"
The patterns Pet (Dog, weight) and Pet (Dog, _) would otherwise match the same values (with the latter not binding a name to the weight).
An equivalent with if/else would look like:
let sound = function
| Pet (Dog, weight) ->
if weight < 10 then "Yip!"
else "Woof!"
| Pet (Cat, weight) ->
if weight > 100 -> "ROAR!!!"
else "Meow!"
In many ways which you prefer boils down to opinion, and which you feel is more expressive.

Regarding OCaml Pattern Matching Syntax

I am following this OCaml tutorial.
They provided the two functions below and said that they are equivalent.
let string_of_int x = match x with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
let string_of_int2 = function
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
My query is regarding the syntax of the above functions.
I wrote the same function but instead of | 0 -> I simply did 0 -> and the function still works in the same way. Is there any particular reason that the tutorial added the extra | in their function?
In the second function what is the use of the function keyword and why was this keyword absent in the first function?
Some people think it looks nicer and more organized, and it allows you to change the order of cases using cut & paste without having to worry about which one didn't have the |.
The function syntax is an abbreviation: function [CASES] is the same as fun x -> match x with [CASES]. There is a subtle difference, which is with function it is not possible to shadow another variable by the name of the parameter.
let string_of_int x = [EXP] is itself an abbreviation for let string_of_int = fun x -> [EXP].
So, to a close approximation, the "canonical" syntax uses fun and match, everything else is sugar. If you apply these two expansions to the two versions of the function, you will see that the same code results (modulo alpha-equivalence, of course :) ).

Write a function with different return types in OCaml

How can I re-write this function in OCaml so that it allows the elements of the tuple to have different types
let nth i (x,y,z) =
match i with
1->x
|2->y
|3->z
|_->raise (Invalid_argument "nth")
The short answer is that it's not possible. OCaml is strongly and statically typed. A function returns a single type. Since your function returns x, y, and z in different cases, then these must all be the same type.
OCaml types are not like types in the so-called dynamically typed languages. You need to think differently. The benefits are (in my opinion) tremendous.
It can be done, but you need to fulfill the constraint that all values, returned from the function should be members of one type. The easiest solution is:
let nth i (x,y,z) =
match i with
| 1 -> `Fst x
| 2 -> `Snd y
| 3 -> `Thd z
| _ -> invalid_arg "nth tuple"
The solution demonstrates that you need to address all possible cases for the types of your tuple. Otherwise, your program will not be well-formed, and this contradicts with the static typing. The latter guarantees that your program is well-formed for any input, so that it wont fail in a runtime.
A twin solution, using ordinary ADT instead of polymorphic ones, will look something like this:
type ('a,'b,'c) t =
| Fst of 'a
| Snd of 'b
| Thd of 'c
let nth i (x,y,z) =
match i with
| 1 -> Fst x
| 2 -> Snd y
| 3 -> Thd z
| _ -> invalid_arg "nth tuple"
An exotic solution (not very practible, maybe) that uses GADT to form an existential type will look like this:
type t = Dyn : 'a -> t
let nth i (x,y,z) =
match i with
| 1 -> Dyn x
| 2 -> Dyn y
| 3 -> Dyn z
| _ -> invalid_arg "nth tuple"

Pattern matching and constructors

Why do i get errors when I write this kind of pattern matching :
type t = A of int | B of float
let f = function
| (A i | B f) -> true
| _ -> false
or
let f = function
| A i | B f -> true
| _ -> false
Error: Variable f must occur on both sides of this | pattern
let f = function
| (A i | B i) -> true
| _ -> false
or
let f = function
| A i | B i -> true
| _ -> false
Error: This pattern matches values of type ints of type float
but a pattern was expected which matches value
If you provide a single right-hand side for multiple patterns (as you do), OCaml requires that the patterns consistently bind to pattern variables.
In the first situation,
match ... with
| A i | B f -> ...
...
the patterns don't agree on the variables they bind to: the first pattern binds to i, while the second binds to f.
In the second situation,
match ... with
| A i | B i -> ...
...
the patterns don't agree on the type of values to bind to their variables: the first pattern binds a value of type int to i, while the second binds a value of type float to i.
The only way in which these two pattern can consistently bind to variables is not to bind to any variables at all:
match ... with
| A _ | B _ -> ...
...
The complete example then becomes
type t = A of int | B of float
let f = function
| A _ | B _ -> true
| _ -> false
(But note that the last arm of the pattern match is superfluous as the first two pattern already exhaustively match all values of your type t. Hence, we get:
let f = function
| A _ | B _ -> true
This of course is equivalent to writing let f _ = true.)
In Or pattern (| pattern), you lose track of which constructors you are in. Therefore, you need to bind the same set of variables to work without referring to constructors.
And OCaml is strongly-typed; a value i cannot have both type int and type float.
If type t has more than two cases, you should write:
let f = function
| A _ | B _ -> true
| _ -> false
otherwise:
let f = function
| A _ | B _ -> true
is enough since pattern matching is already exhaustive.
I agree that Or pattern is quite restrictive, but sometimes it is helpful when you have symmetric cases in your function:
type num =
| Int of int
| Float of float
let add s1 s2 =
match s1, s2 with
| Int i1, Int i2 -> Int (i1 + i2)
| Int i, Float f | Float f, Int i -> Float (float i +. f)
| Float f1, Float f2 -> Float (f1 +. f2)

OCaml: Pattern matching vs If/else statements

So, I'm totally new to OCaml and am moving pretty slowly in getting my first functions implemented. One thing I'm having trouble understanding is when to use pattern matching abilities like
let foo =
[] -> true
| _ -> false;;
vs using the if else structure like
let foo a =
if a = [] then true else false;;
When should I use each?
I don't think there's a clear cut answer to that question. First, the obvious case of pattern matching is when you need destructing, e.g.:
let rec sum = function
| [] -> 0
| head :: tail -> head + sum tail;;
Another obvious case is when you're defining a recursive function, pattern matching make the edge condition clearer, e.g.:
let rec factorial = function
| 0 -> 1
| n -> n * factorial(n - 1);;
instead of:
let rec factorial = function n ->
if n = 0 then
1
else
n * factorial(n-1);;
That might not be a great example, just use your imagination to figure out more complex edge conditions! ;-)
In term of regular (say C like) languages, I could say that you should use pattern matching instead of switch/case and if in place of the ternary operator. For everything else it's kind of a grey zone but pattern matching is usually preferred in the ML family of languages.
As far as I know the signifincant difference is that the expression at the guards in the match statement is a pattern which means you can do things that allow you to break apart the shape (destruct) the matched expression, as Nicolas showed in his answer. The other implication of this is that code like this:
let s = 1 in
let x = 2 in
match s with
x -> Printf.printf "x does not equal s!!\n" x
| _ -> Printf.printf "x = %d\n" x;
won't do what you expect. This is because x in the match statement does not refer to the x in the let statement above it but it's a name of the pattern. In cases like these you'd need to use if statements.
For me if..then..else is equivalent to match .. with | true -> .. | false -> .., but there's a syntax sugar if you are facing cases with nested pattern matching, using if..else in an interlace way can help you avoiding to use begin...end to separate different level of patterns
match .. with
| true ->
if .. then
match .. with
| true -> ..
| false -> ..
else
...
| false -> ...
is more compact than
match .. with
| true ->
begin
match .. with
| true ->
begin
match .. with
| true -> ..
| false -> ..
end
| false ->
...
end
| false -> ...
Pattern matching allows for deconstruction of compound data types, and in general, the ability to match pattern within a given data structure, rather than using conditionals like the if.. then structure. Pattern matching can also be used for boolean equality cases using the |x when (r == n) type construct. I should also add pattern matching is a lot more efficient than if... then.. constructs, so use it liberally!

Resources