-
Notifications
You must be signed in to change notification settings - Fork 36
Learning of Context‐Free Grammars
Edi Muškardin edited this page Dec 13, 2023
·
5 revisions
AALpy supports the learning of visibly deterministic pushdown automata, which can be a subset of all context-free grammars.
Visibly deterministic pushdown automata
-
visiblyrefers to the fact that the user has to specify, in the alphabet, which symbols are internal, call, and return -
callsymbols push on the stack -
returnsymbols pop from stack -
internalsymbols do not affect the stack -
deterministicpushdown automata refers to the fact that the behavior of learned pushdown automata is deterministic, so it cannot, for example, learn languages like palindromes
Note that call, return, internal are disjoint sets.
In the following example, we demonstrate how to learn a model that can recognize regular expressions:
from aalpy.base import SUL
from aalpy.automata import SevpaAlphabet
from aalpy.oracles import RandomWordEqOracle
from aalpy.learning_algs import run_KV
import warnings
import ast
warnings.filterwarnings("ignore")
class ArithmeticSUL(SUL):
def __init__(self):
super().__init__()
self.string_under_test = ''
def pre(self):
self.string_under_test = ''
def post(self):
pass
def step(self, letter):
if letter:
self.string_under_test += ' ' + letter if len(self.string_under_test) > 0 else letter
try:
# Parse the expression using ast
parsed_expr = ast.parse(self.string_under_test, mode='eval')
# Check if the parsed expression is a valid arithmetic expression
is_valid = all(isinstance(node, (ast.Expression, ast.BinOp, ast.UnaryOp, ast.Num, ast.Name, ast.Load))
or isinstance(node, ast.operator) or isinstance(node, ast.expr_context)
or (isinstance(node, ast.BinOp) and isinstance(node.op, ast.operator))
for node in ast.walk(parsed_expr))
return is_valid
except SyntaxError:
return False
sul = ArithmeticSUL()
alphabet = SevpaAlphabet(internal_alphabet=['1', '+'], call_alphabet=['('], return_alphabet=[')'])
eq_oracle = RandomWordEqOracle(alphabet.get_merged_alphabet(), sul, min_walk_len=2,
max_walk_len=10, num_walks=2000)
learned_model = run_KV(alphabet, sul, eq_oracle, automaton_type='vpa')
learned_model.visualize()Resulting in the following model:
This model can be interpreted as: WIP