from symbol import is_terminal, is_nonterminal

is_terminal('a')

is_nonterminal('[X]')

"""
Explanation: CFG
This is how we represent a CFG
Symbols
Its symbols are plain python strings. 
A nonterminal is a brackted string such as
    [S]
End of explanation
"""


from rule import Rule

r = Rule('[S]', ['[X]', 'a'], 1.0)

"""
Explanation: Rules
Rules are objects made of a LHS symbol, a RHS sequence (of symbols) and a probability.
End of explanation
"""


print r

print r.prob

r in set([r])

D = {r: 1}
D

"""
Explanation: You can print a rule, you can access its attributes, and you can hash rules with containers such as dict and set.
End of explanation
"""


from cfg import WCFG

G = WCFG()

"""
Explanation: Grammar
A PCFG is organised pretty much as a dictionary mapping from LHS symbols to their rewrite rules.
End of explanation
"""


G.add(Rule('[S]', ['[X]'], 0.0))

G.add(Rule('[S]', ['[S]', '[X]'], 0.0))
G.add(Rule('[X]', ['a'], 0.0))

"""
Explanation: We can add rules
End of explanation
"""


print G

"""
Explanation: We can print the grammar
End of explanation
"""


G.can_rewrite('[S]')

G.can_rewrite('a')

"""
Explanation: we can test whether there are rewrite rules for a certain LHS symbol
End of explanation
"""


G.get('[S]')

G.get('[X]')

"""
Explanation: we can get the set of rewrite rules for a certain LHS symbol
End of explanation
"""


G.get('a')

"""
Explanation: and when a symbol cannot be rewritten, the grammar will return an empty set
End of explanation
"""


sum(1 for r in G)

"""
Explanation: We can also iterate through rules in the grammar.
Note that the followin is basically counting how many rules we have in the grammar.
End of explanation
"""


len(G)

"""
Explanation: which can also be done in a more efficient way
End of explanation
"""


'[S]' in G.nonterminals

'a' in G.terminals

"""
Explanation: Finally we can have access to the set of terminals and nonterminals of the grammar
End of explanation
"""


from cfg import read_grammar_rules

"""
Explanation: Read from file
Grammar files contain one rule per line.
Each line is a triple with fields separated by '|||'.
The first field is the rule's LHS symbol, the second symbol is the rule's RHS sequence, and the last field is the rule's probability.
Example:
    [S] ||| [S] [X] ||| 0.5
End of explanation
"""


# first we open a file
istream = open('examples/arithmetic')

# then we read rules from this file initialising a WCFG object
G1 = WCFG(read_grammar_rules(istream))

print G1

"""
Explanation: We hava a simple grammar for arithmetic operations. This grammar knows that products have precedence over summation.
End of explanation
"""


G2 = WCFG(read_grammar_rules(open('examples/ambiguous')))
print G2

"""
Explanation: We also have an ambiguous grammar which discourage solving sums before solving products, but still allows it.
End of explanation
"""


