Clean up some unused functions
This commit is contained in:
parent
6353522827
commit
57130c9233
183
build_oracle.py
183
build_oracle.py
|
@ -147,49 +147,6 @@ def _predict(
|
|||
else:
|
||||
return first_rhs
|
||||
|
||||
def oracle(
|
||||
is_term: Callable[[A | B | C], TypeGuard[B]],
|
||||
is_var: Callable[[A | B | C], TypeGuard[A]],
|
||||
grammar: Sequence[Tuple[A, Sequence[A | B | C]]],
|
||||
) -> Callable[[A, B], Collection[Sequence[A | B | C]]]:
|
||||
"""
|
||||
Show valid expansions of a variable based on the next terminal to be read
|
||||
|
||||
For valid LL(1) grammars, there should never be more than one valid expansion.
|
||||
|
||||
The inner method constructed is memoized for your convenience.
|
||||
|
||||
>>> is_tok = p_instance(Tok)
|
||||
>>> is_var = p_instance(Variable)
|
||||
>>> my_oracle = oracle(is_tok, is_var, GRAMMAR)
|
||||
|
||||
One valid expansion:
|
||||
>>> my_oracle(Variable.Clauses_, Tok.Negate)
|
||||
[[<Clause>, <Clauses>]]
|
||||
|
||||
One valid expansion, but it expands to epsilon:
|
||||
>>> my_oracle(Variable.Clauses_, Tok.Eof)
|
||||
[[]]
|
||||
|
||||
Zero valid expansions:
|
||||
>>> my_oracle(Variable.Term, Tok.Newline)
|
||||
[]
|
||||
"""
|
||||
is_not_c: Callable[[A | B | C], TypeGuard[A | B]] = lambda x: is_term(x) or is_var(x) #type:ignore
|
||||
e_grammar: Sequence[Tuple[A, Sequence[A | B]]] = _erase_actions(grammar, is_not_c)
|
||||
follow = _follow(is_term, e_grammar)
|
||||
|
||||
@wraps(oracle)
|
||||
@cache
|
||||
def inner(v: A, c: B) -> Collection[Sequence[A | B | C]]:
|
||||
return [
|
||||
handle
|
||||
for (lhs, handle) in grammar
|
||||
if lhs == v
|
||||
and c in _predict(is_term, e_grammar, follow, lhs, _erase_actions_h(handle, is_not_c))
|
||||
]
|
||||
return inner
|
||||
|
||||
def oracle_table(
|
||||
is_term: Callable[[A | B], TypeGuard[B]],
|
||||
is_var: Callable[[A | B], TypeGuard[A]],
|
||||
|
@ -218,142 +175,24 @@ def oracle_table(
|
|||
"""
|
||||
all_variables = { lhs for (lhs, rhs) in grammar }
|
||||
all_terminals = { symbol for (lhs, rhs) in grammar for symbol in rhs if is_term(symbol) }
|
||||
the_oracle = oracle(is_term, is_var, grammar)
|
||||
|
||||
is_not_c: Callable[[A | B | C], TypeGuard[A | B]] = lambda x: is_term(x) or is_var(x) #type:ignore
|
||||
e_grammar: Sequence[Tuple[A, Sequence[A | B]]] = _erase_actions(grammar, is_not_c) #type:ignore
|
||||
follow = _follow(is_term, e_grammar)
|
||||
|
||||
return {
|
||||
v: {
|
||||
t: the_oracle(v, t)
|
||||
t: [
|
||||
handle
|
||||
for (lhs, handle) in grammar
|
||||
if lhs == v
|
||||
and t in _predict(is_term, e_grammar, follow, lhs, _erase_actions_h(handle, is_not_c)) #type:ignore
|
||||
]
|
||||
for t in all_terminals
|
||||
}
|
||||
for v in all_variables
|
||||
}
|
||||
|
||||
def print_oracle_table(
|
||||
oracle_table: Mapping[A, Mapping[B, Collection[Sequence[A | B]]]],
|
||||
render: Callable[[A | B], str],
|
||||
) -> str:
|
||||
"""
|
||||
Pretty prints an oracle table
|
||||
|
||||
The render function is expected to render terminals and variables. If the render
|
||||
function produces valid python, then `print_oracle_table` will also produce valid
|
||||
python.
|
||||
|
||||
### Example:
|
||||
|
||||
We generate a simple grammar:
|
||||
|
||||
>>> class SimpleVariable(IntEnum):
|
||||
... Sum = auto()
|
||||
... Sum_ = auto()
|
||||
... Term = auto()
|
||||
|
||||
>>> class SimpleTerminal(IntEnum):
|
||||
... Number = auto()
|
||||
... Letter = auto()
|
||||
... Plus = auto()
|
||||
|
||||
>>> grammar = [
|
||||
... (SimpleVariable.Sum, [SimpleVariable.Term, SimpleVariable.Sum_]),
|
||||
... (SimpleVariable.Sum_, [SimpleTerminal.Plus, SimpleVariable.Sum]),
|
||||
... (SimpleVariable.Sum_, []),
|
||||
... (SimpleVariable.Term, [SimpleTerminal.Number]),
|
||||
... (SimpleVariable.Term, [SimpleTerminal.Letter]),
|
||||
... ]
|
||||
|
||||
>>> is_tok = p_instance(SimpleTerminal)
|
||||
>>> is_var = p_instance(SimpleVariable)
|
||||
>>> my_oracle_table = oracle_table(is_tok, is_var, grammar)
|
||||
>>> rendered_oracle_table = print_oracle_table(my_oracle_table, lambda e: f'{e.__class__.__name__}.{e.name}')
|
||||
>>> print(rendered_oracle_table) #doctest: +NORMALIZE_WHITESPACE
|
||||
{
|
||||
SimpleVariable.Sum: {
|
||||
SimpleTerminal.Number: [[SimpleVariable.Term, SimpleVariable.Sum_]],
|
||||
SimpleTerminal.Letter: [[SimpleVariable.Term, SimpleVariable.Sum_]],
|
||||
SimpleTerminal.Plus: []
|
||||
},
|
||||
SimpleVariable.Sum_: {
|
||||
SimpleTerminal.Number: [],
|
||||
SimpleTerminal.Letter: [],
|
||||
SimpleTerminal.Plus: [[SimpleTerminal.Plus, SimpleVariable.Sum]]
|
||||
},
|
||||
SimpleVariable.Term: {
|
||||
SimpleTerminal.Number: [[SimpleTerminal.Number]],
|
||||
SimpleTerminal.Letter: [[SimpleTerminal.Letter]],
|
||||
SimpleTerminal.Plus: []
|
||||
}
|
||||
}
|
||||
"""
|
||||
return '{\n' + ",\n".join([
|
||||
f'{render(v)}: {"{"}\n' + ',\n'.join([
|
||||
f'\t{render(t)}: [' + ', '.join([
|
||||
'[' + ', '.join([
|
||||
render(symbol)
|
||||
for symbol in expansion
|
||||
]) + ']'
|
||||
for expansion in expansions
|
||||
]) + ']'
|
||||
for (t, expansions) in term_table.items()
|
||||
]) + '\n}'
|
||||
for (v, term_table) in oracle_table.items()
|
||||
]) + '\n}'
|
||||
|
||||
EA = TypeVar('EA', bound=Enum)
|
||||
EB = TypeVar('EB', bound=Enum)
|
||||
def print_oracle_table_enum(
|
||||
oracle_table: Mapping[A, Mapping[B, Collection[Sequence[A | B]]]]
|
||||
) -> str:
|
||||
"""
|
||||
A special case of `print_oracle_table` where tokens and variables are enums
|
||||
|
||||
Always produces valid python.
|
||||
|
||||
### Example:
|
||||
|
||||
We generate a simple grammar:
|
||||
|
||||
>>> class SimpleVariable(IntEnum):
|
||||
... Sum = auto()
|
||||
... Sum_ = auto()
|
||||
... Term = auto()
|
||||
|
||||
>>> class SimpleTerminal(IntEnum):
|
||||
... Number = auto()
|
||||
... Letter = auto()
|
||||
... Plus = auto()
|
||||
|
||||
>>> grammar = [
|
||||
... (SimpleVariable.Sum, [SimpleVariable.Term, SimpleVariable.Sum_]),
|
||||
... (SimpleVariable.Sum_, [SimpleTerminal.Plus, SimpleVariable.Sum]),
|
||||
... (SimpleVariable.Sum_, []),
|
||||
... (SimpleVariable.Term, [SimpleTerminal.Number]),
|
||||
... (SimpleVariable.Term, [SimpleTerminal.Letter]),
|
||||
... ]
|
||||
|
||||
>>> is_tok = p_instance(SimpleTerminal)
|
||||
>>> is_var = p_instance(SimpleVariable)
|
||||
>>> my_oracle_table = oracle_table(is_tok, is_var, grammar)
|
||||
>>> rendered_oracle_table = print_oracle_table_enum(my_oracle_table)
|
||||
>>> print(rendered_oracle_table) #doctest: +NORMALIZE_WHITESPACE
|
||||
{
|
||||
SimpleVariable.Sum: {
|
||||
SimpleTerminal.Number: [[SimpleVariable.Term, SimpleVariable.Sum_]],
|
||||
SimpleTerminal.Letter: [[SimpleVariable.Term, SimpleVariable.Sum_]],
|
||||
SimpleTerminal.Plus: []
|
||||
},
|
||||
SimpleVariable.Sum_: {
|
||||
SimpleTerminal.Number: [],
|
||||
SimpleTerminal.Letter: [],
|
||||
SimpleTerminal.Plus: [[SimpleTerminal.Plus, SimpleVariable.Sum]]
|
||||
},
|
||||
SimpleVariable.Term: {
|
||||
SimpleTerminal.Number: [[SimpleTerminal.Number]],
|
||||
SimpleTerminal.Letter: [[SimpleTerminal.Letter]],
|
||||
SimpleTerminal.Plus: []
|
||||
}
|
||||
}
|
||||
"""
|
||||
return print_oracle_table(oracle_table, lambda e: f'{e.__class__.__name__}.{e.name}') #type: ignore
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
from grammar import GRAMMAR, Tok, Variable
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cat << EOF > oracle_table.py
|
||||
from grammar import Tok, Variable
|
||||
|
||||
oracle_table = (
|
||||
EOF
|
||||
|
||||
if python grammar.py >> oracle_table.py; then
|
||||
echo ")" >> oracle_table.py
|
||||
echo "Built oracle_table.py"
|
||||
else
|
||||
rm oracle_table.py
|
||||
python build_oracle.py
|
||||
fi
|
|
@ -135,19 +135,6 @@ def derive2(kb1: KnowledgeBase_, kb2: KnowledgeBase_) -> KnowledgeBase:
|
|||
for clause in merge_clauses(c1, c2)
|
||||
)
|
||||
|
||||
is_false: Callable[[Clause_], bool] = c(p(eq, 0), len)
|
||||
"""
|
||||
Determines whether a clause is equivalent to false
|
||||
|
||||
This is only true for the empty clause.
|
||||
|
||||
>>> is_false([])
|
||||
True
|
||||
|
||||
>>> is_false([IRProp('real')])
|
||||
False
|
||||
"""
|
||||
|
||||
false_clause: Clause = FSet()
|
||||
"""
|
||||
The clause which represents the logical condition False
|
||||
|
|
Loading…
Reference in a new issue