assume we have a context free grammar , if it is in LL[1] , then it has only right Associative !
but let's say i want to make this context free grammar have a left Associative , then it will not stay in LL[1] , (which is okay)
i figured that in order to make a context free grammar have a left Associative i should make it have left recursion .
is there is a way to include left recursion to a context free grammar without changing the language of the grammar ?
for example if we have this context free grammar :
1: S -> sum ( ELIST )
2: ELIST -> E , ELIST
3: ELIST -> E
4: E -> num
5: E -> id
6: E -> S
how to make this include a left recursion so the operator "," will now be left Associative ?
Change your second production to:
2: ELIST -> ELIST , E
This does not change the language, only the way the language is parsed.
This modification should work with any expression grammar written in cascading precedence style. But it is not a transformation which can be applied to any grammar whatsoever.
I'm working on a solution for a problem for the advent of code 2018 (spoiler alert) where I need a function which takes a string (or a char list) and removes every pair of chars when they react. The exercise describes two chars, or "elements" in a "polymer", reacting when they are the same letter but only differ in case; so starting out with AbBc would leave you with Ac. Keep in mind that after a reaction two chars could end up next to each other, where they weren't before, and cause a new reaction.
I thought I could solve this by using a recursive function which only deals with the first two chars and recursively calls itself, but since the input string is quite large, this causes a stackoverflow exception:
let rec react polymer =
match polymer with
| [] -> []
| [x] -> [x]
| head::tail ->
let left = head
let right = List.head tail
let rest = List.tail tail
// 'reacts' takes two chars and
// returns 'true' when they react
match reacts left right with
// when reacts we go further with
// the rest as these two chars are
// obliterated
| true -> react rest
// no reaction means the left char
// remains intact and the right one
// could react with the first char
// of the rest
| false -> [left] # react tail
Then, just trying to solve the exercise to have a right answer to unit test against, I tried to do it imperatively, but that got messy real quick and now I'm kinda stuck. I'm teaching myself f# so any pointers are welcome. Can anyone solve this in a functional manner?
You can avoid stack overflow by rewriting your function to use tail recursion, which just means that the recursive call should be the last operation to execute.
When you do [left] # react tail you first make a recursive call, and then append [left] to the result of that. That means it has to keep the current function context, called a stack frame, around while it executes the recursive call, and if that recurses as well the stack frames add up until you get a stack overflow. But if there's no more work to be done in the current function context, the stack frame can be released (or reused), hence no stack overflow.
You can make it tail recursive by adding another function argument, conventionally called acc since it "accumulates" values. Instead of adding left to the return value of the recursive call we add it to the accumulator and pass that along. Then when we exhaust the input, we return the accumulator instead of the empty list.
I've also taken the liberty of the append, [left] # ..., as a cons, left::..., since the latter is much more efficient than the former. I've also moved left, right and rest to the pattern, since that's much neater and safer. You should generally avoid using List.head and List.tail since they fail on empty lists and are bugs just waiting to happen.
let rec react acc polymer =
match polymer with
| [] -> acc
| [x] -> x::acc
| left::right::rest ->
match reacts left right with
| true -> react acc rest
| false -> react (left::acc) (right::rest)
You could also use a guard instead of nested matches (which should really have been an if anyway):
let rec react acc polymer =
match polymer with
| [] ->
acc
| [x] ->
x::acc
| left::right::rest when reacts left right ->
react acc rest
| left::rest ->
react (left::acc) rest
I have a BNF for a recursive descent parser. One of the steps to solving this is to verify that the grammar is LL(1), but I keep coming up with verification that it is not.
The BNF in question, or more specifically, the exact area I'm having an issue:
<S> -> start <vars> <block>
<block> -> begin <vars> <stats> end
<vars> -> e | id = number <vars>
<stats> -> <if> | <block> | <loop> | <assign>
There is more to this, but these are the only productions that are relevant to this question, I believe.
My approach to solving this is to compute FIRST of the right hand sides of those productions that have a choice. If there is no choice, I skip, as I know they are already k=0.
FIRST(e | id = number <vars>) = {e, id} // Since it produces the empty set, I must also compute follow.
FOLLOW( e | id = number <vars> ) = FOLLOW(<vars>)
Non-terminal 'vars' appears in 2 productions: and , and is followed by two nonterminals: 'block' and 'stats'
FIRST(<block>) = {begin}
FIRST(<stats>) = { ... begin ... } // contains all terminals
Now, my problem. In computing the FOLLOW(), I have found two begin tokens, which leads me to say that this grammar is not LL(1). However, I don't believe that the answer to this exercise is that it is not possible to create a recursive descent parser, so I believe that I've made an error somewhere or that I have executed the algorithm incorrectly.
Can anyone point me in the right direction?
So you've correctly found that FOLLOW(var) = FIRST(block) ∪ FIRST(stats). These are all sets, so when you compute the union of the two first sets (each of which contains begin), you end up with just a single begin. As long as neither of these sets ends up containing id, everything is fine and your grammar is still LL(1).
So I am trying to draw the decision of tree of 2 Prolog problems, one that uses the accumulator and other that doesn't. Here are my problems and the solutions I did, respectively:
length([H|T],N) :- length(T,N1), N is N1+1.
length([ ],0).
Goal: ?: length([1,2,3],N)
Second one with accumulator:
length_acc(L,N) :- len_acc(L,0,N).
len_acc([H|T], A, N) :- A1 is A+1, len_acc(T, A1, N).
len_acc([], A, A).
Goal: ?-length_acc([1,2], N).
Are the decision trees correctly drawn? Or have I made a mistake? Whats the correct way to draw these kind of recursive decision tree?
Thanks.
The tree you are referring to is usually called a search-tree aka SLD-tree, not to be confused with a proof-tree.
Both the problems you have outlined are the most simple cases of search-trees:
there is only one solution
the query does not fail
each step in the search can only match a single clause (empty list vs non-empty list)
These three characteristics imply that there will only be a single branch in the SLD tree.
You'll get the following search-trees:
Note that for it to be a correct search-tree, at most one goal is resolved in each step, which makes search-trees very large... therefore it's common that people make simplified trees where multiple goals can be resolved in each step, which arguably are not true search-trees but illustrates the search in a more succint way.
Edges in the tree are labeled with substitutions that are applied to the variables as part of the unification algorithm.
Search-trees correspond closely to traces, and you can usually do a straight translation from a trace of your program to a search tree.
I advise you to study search-trees for queries that have multiple answers and branches that can fail, which gives more interesting trees with multiple branches. An example from The Art of Prolog by Sterling, Shapiro:
Program:
father(abraham, isaac). male(isaac)
father(haran, lot). male(lot).
father(haran, milcah). female(milcah).
father(haran, yiscah). female(yiscah).
son(X,Y):- father(Y,X), male(X).
daughter(X,Y):- father(Y,X), female(X).
Query:
?: son(S, haran)
Search-tree:
A nice way to understand something is to re-implement it yourself.
It's especially nice to implement Prolog when you already have Prolog to implement it with. :)
program( patriarchs, P ) :-
P = [ % [son(S, haran)] , % Resolvent
[father(abraham, isaac)] % Clauses...
, [father(haran, lot)] % [Head, Body...]
, [father(haran, milcah)]
, [father(haran, yiscah)]
, [male(isaac)]
, [male(lot)]
, [female(milcah)]
, [female(yiscah)]
, [son(X,Y), father(Y,X), male(X)]
, [daughter(X,Y), father(Y,X), female(X)]
].
solve( Program ):-
Program = [[] | _]. % empty resolvent -- success
solve( [[Goal | Res] | Clauses] ) :-
member( Rule, Clauses),
copy_term( Rule, [Head | Body]), % rename vars
Goal = Head, % unify head
append( Body, Res, Res2 ), % replace goal
solve( [Res2 | Clauses] ).
query( What, Query ):- % Query is a list of Goals to Solve
program( What, Program),
solve( [ Query | Program ] ).
Testing,
23 ?- query( patriarchs, [son(S, haran)] ).
S = lot ;
false.
Now the above solve/1 can be augmented to record the record of successful instantiations of Goal making the unifications Goal = Head possible.
I am somewhat new to F#, and I came across some strange behaviour when I was working with some recursive functions. I have two different versions of it below:
Version 1:
This causes a stack overflow, though it seems that it shouldn't (at least to my noob eyes)
let rec iMake acc =
match acc with
| 10 -> 100
| _ -> iMake acc+1
Version2:
This one works as I would expect it to.
let rec iMake acc =
match acc with
| 10 -> 100
| _ -> iMake (acc+1)
The only difference is that version 2 puts the acc+1 expression into parenthesis. So my question is, why does the first version not work, but the second one does? Does this mean that I should put all of my function arguments into parenthesis to avoid this type of stuff in the future ?
Function call has higher precedence than binary operator +. So the first function actually works like:
let rec iMake acc =
match acc with
| 10 -> 100
| _ -> (iMake acc)+1