Skip to content

Commit

Permalink
add PAPNI: passive learning of VPAs
Browse files Browse the repository at this point in the history
  • Loading branch information
emuskardin committed Sep 27, 2024
1 parent 76eeadc commit 3788ea4
Show file tree
Hide file tree
Showing 13 changed files with 1,098 additions and 223 deletions.
84 changes: 73 additions & 11 deletions Examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,24 +799,21 @@ def rpni_example():


def rpni_check_model_example():
import random
from aalpy.SULs import AutomatonSUL
from aalpy.learning_algs import run_RPNI
from aalpy.oracles import StatePrefixEqOracle
from aalpy.utils import generate_random_moore_machine, generate_random_dfa
from aalpy.utils import generate_random_moore_machine
from aalpy.utils import generate_input_output_data_from_automata, convert_i_o_traces_for_RPNI

model = generate_random_dfa(num_states=5, alphabet=[1, 2, 3], num_accepting_states=2)
# model = generate_random_dfa(num_states=5, alphabet=[1, 2, 3], num_accepting_states=2)
model = generate_random_moore_machine(num_states=5, input_alphabet=[1, 2, 3], output_alphabet=['a', 'b'])

input_al = model.get_input_alphabet()

num_sequences = 1000
data = []
for _ in range(num_sequences):
seq_len = random.randint(1, 20)
random_seq = random.choices(input_al, k=seq_len)
output = model.compute_output_seq(model.initial_state, random_seq)[-1]
data.append((random_seq, output))
data = generate_input_output_data_from_automata(model, num_sequances=2000,
min_seq_len=1, max_seq_len=12)

data = convert_i_o_traces_for_RPNI(data)

rpni_model = run_RPNI(data, automaton_type='moore', print_info=True)

Expand All @@ -830,7 +827,7 @@ def rpni_check_model_example():
if cex is None:
print("Could not find a counterexample between the RPNI-model and the original model.")
else:
print('Counterexample found. Either RPNI data was incomplete, or there is a bug in RPNI algorithm :o ')
print('Counterexample found. Either RPNI data was incomplete (or there is a bug in RPNI algorithm :o )')


def rpni_mealy_example():
Expand Down Expand Up @@ -1062,3 +1059,68 @@ def random_sevpa_learning():
model = run_KV(alphabet=alphabet, sul=sul, eq_oracle=eq_oracle, automaton_type='vpa',
print_level=2, cex_processing='rs')


def passive_vpa_learning_on_lists():
from aalpy.learning_algs import run_PAPNI
from aalpy.automata import VpaAlphabet

vpa_alphabet = VpaAlphabet(internal_alphabet=['1'], call_alphabet=['(', '['], return_alphabet=[')', ']'])

list_data = [
(tuple(), False),
(('[', '[', ']', ']'), True),
(('(', '(', ')', ')'), True),

(('[', '[', ']', ')'), False),
(('[', '[', ')', ']'), False),
(('[', ')'), False),
(('(', ']'), False),
(('[', '[', ']', '1', ']'), True),
(('[', '1', '[', ']', '1', ']'), True),
(('(', '1', '[', ']', '1', ')'), True),
(('(', ')'), True),
(('[', ']'), True),
(('[', '1', '(', ']', '1', ')'), False),
]

papni = run_PAPNI(list_data, vpa_alphabet, algorithm='gsm', print_info=True)
papni.visualize()


def passive_vpa_learning_arithmetics():
from aalpy.learning_algs import run_PAPNI
from aalpy.utils.BenchmarkVpaModels import gen_arithmetic_data
arithmetic_data, vpa_alphabet = gen_arithmetic_data(num_sequances=4000, min_seq_len=2, max_seq_len=10)

print(f"Alphabet: {vpa_alphabet}")

print('Data:')
for i in range(10):
print(arithmetic_data[i])

learned_model = run_PAPNI(arithmetic_data, vpa_alphabet)
learned_model.visualize()


def passive_vpa_learning_on_all_benchmark_models():
from aalpy.learning_algs import run_PAPNI
from aalpy.utils.BenchmarkVpaModels import get_all_VPAs
from aalpy.utils import generate_input_output_data_from_vpa, convert_i_o_traces_for_RPNI

for gt in get_all_VPAs():

vpa_alphabet = gt.input_alphabet
data = generate_input_output_data_from_vpa(gt, num_sequances=2000, min_seq_len=1, max_seq_len=16)

data = convert_i_o_traces_for_RPNI(data)

papni = run_PAPNI(data, vpa_alphabet, algorithm='gsm', print_info=True)

for seq, o in data:
papni.reset_to_initial()
learned_output = papni.execute_sequence(papni.initial_state, seq)[-1]
if o != learned_output:
print(seq, o, learned_output)
assert False, 'Papni Learned Model not consistent with data.'

print('PAPNI model conforms to data.')
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ AALpy supports both **active** and **passive** automata learning algorithms that
| Deterministic | DFAs <br /> Mealy Machines <br /> Moore Machines | L* <br /> KV <br /> RPNI | Seamless Caching <br /> Counterexample Processing <br /> 13 Equivalence Oracles |
| Non-Deterministic | ONFSM <br /> Abstracted ONFSM | L*<sub>ONFSM</sub> | Size Reduction Trough Abstraction |
| Stochastic | Markov Decision Processes <br /> Stochastic Mealy Machines <br /> Markov Chains | L*<sub>MDP</sub> <br /> L*<sub>SMM</sub> <br /> ALERGIA | Counterexample Processing <br /> Exportable to PRISM format <br /> Bindings to jALERGIA|
| Pushdown | VPDA/SEVPA | KV<sub>VPA</sub> | Specification of exclusive <br/> call-return pairs
| Pushdown | VPA/SEVPA | KV<sub>VPA</sub> <br /> PAPNI | Passive learning of VPAs <br /> Specification of exclusive <br/> call-return pairs
</div>

## Installation
Expand Down
Loading

0 comments on commit 3788ea4

Please sign in to comment.