Skip to content

Commit b6b2c94

Browse files
author
Edi Muskardin
committed
move PAPNI to separate file
1 parent 9ccf709 commit b6b2c94

File tree

4 files changed

+66
-81
lines changed

4 files changed

+66
-81
lines changed

Benchmarking/passive_vpa_vs_rpni.py renamed to Benchmarking/papni_vs_rpni_benchmarking.py

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,6 @@ def run_experiment(experiment_id,
144144
data += positive_seq[:5000]
145145
data += negative_seq[:10000 - len(data)]
146146

147-
# wm_negative = 0
148-
# for seq, label in data:
149-
# if not label and ground_truth_model.is_balanced(seq):
150-
# wm_negative += 1
151-
# print(wm_negative)
152-
153-
# data = get_sequences_from_active_sevpa(ground_truth_model)
154-
155147
vpa_alphabet = ground_truth_model.get_input_alphabet()
156148

157149
learning_data, test_data = split_data_to_learning_and_testing(data, learning_to_test_ratio=learning_to_test_ratio)
@@ -171,20 +163,10 @@ def run_experiment(experiment_id,
171163
comparison_results = comparison_results + [learning_set_size, num_test_size]
172164
return comparison_results
173165

174-
175-
def run_all_experiments_experiments(test_models, learning_to_test_ratio):
176-
for idx, gt in enumerate(test_models):
177-
results = run_experiment(idx, gt, num_of_learning_seq=10000, max_learning_seq_len=50,
178-
random_data_generation=False, learning_to_test_ratio=learning_to_test_ratio)
179-
180-
res_str = f'GT {idx + 1}:\t Learning ({results[-2][0]}/{results[-2][1]}),\t Test ({results[-1][0]}/{results[-1][1]}),\t'
181-
res_str += f'RPNI: size: {results[0]}, prec/rec/F1: {results[2]}, \t PAPNI size: {results[1]}, prec/rec/F1: {results[3]}'
182-
183-
print(res_str)
184-
185-
186166
def run_experiments_multiple_times(test_models, num_times, learning_to_test_ratio=0.5):
187167
all_results = defaultdict(list)
168+
print(f'Running each experiment/model {num_times} times.')
169+
188170
for idx, gt in enumerate(test_models):
189171
for _ in range(num_times):
190172
r = run_experiment(idx, gt, num_of_learning_seq=10000, max_learning_seq_len=50,
@@ -257,4 +239,7 @@ def test_papni_based_on_sevpa_dataset():
257239

258240
assert in_learning + not_in_learning == balanced_counter
259241

260-
test_papni_based_on_sevpa_dataset()
242+
#test_papni_based_on_sevpa_dataset()
243+
244+
all_models = get_all_VPAs()
245+
run_experiments_multiple_times(all_models, num_times=2)

aalpy/learning_algs/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
from .stochastic.StochasticLStar import run_stochastic_Lstar
99
from .stochastic_passive.Alergia import run_Alergia, run_JAlergia
1010
from .stochastic_passive.ActiveAleriga import run_active_Alergia
11-
from .deterministic_passive.RPNI import run_RPNI, run_PAPNI
11+
from .deterministic_passive.RPNI import run_RPNI
12+
from .deterministic_passive.PAPNI import run_PAPNI
1213
from .deterministic_passive.active_RPNI import run_active_RPNI
1314
from .general_passive.GeneralizedStateMerging import run_GSM
1415
from .general_passive.GsmAlgorithms import run_EDSM, run_Alergia_EDSM, run_k_tails
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from aalpy.utils import is_balanced
2+
from aalpy.automata.Vpa import vpa_from_dfa_representation
3+
4+
def run_PAPNI(data, vpa_alphabet, algorithm='edsm', print_info=True):
5+
"""
6+
Run PAPNI, a deterministic passive model learning algorithm of deterministic pushdown automata.
7+
Resulting model conforms to the provided data.
8+
9+
Args:
10+
11+
data: sequence of input sequences and corresponding label. Eg. [[(i1,i2,i3, ...), label], ...]
12+
vpa_alphabet: grouping of alphabet elements to call symbols, return symbols, and internal symbols. Call symbols
13+
push to stack, return symbols pop from stack, and internal symbols do not affect the stack.
14+
algorithm: either 'gsm' for classic RPNI or 'edsm' for evidence driven state merging variant of RPNI
15+
print_info: print learning progress and runtime information
16+
17+
Returns:
18+
19+
VPA conforming to the data, or None if data is non-deterministic.
20+
"""
21+
from aalpy.learning_algs import run_EDSM, run_RPNI
22+
assert algorithm in {'gsm', 'classic', 'edsm'}
23+
24+
# preprocess input sequences to keep track of stack
25+
papni_data = []
26+
for input_seq, label in data:
27+
# if input sequance is not balanced we do not consider it (it would lead to error state anyway)
28+
if not is_balanced(input_seq, vpa_alphabet):
29+
continue
30+
31+
# for each sequance keep track of the stack, and when pop/return element is observed encode it along with the
32+
# current top of stack. This keeps track of stack during execution
33+
processed_sequance = []
34+
stack = []
35+
36+
for input_symbol in input_seq:
37+
input_element = input_symbol
38+
# if call/push symbol push to stack
39+
if input_symbol in vpa_alphabet.call_alphabet:
40+
stack.append(input_symbol)
41+
# if return/pop symbol pop from stack and add it to the input data
42+
if input_symbol in vpa_alphabet.return_alphabet:
43+
top_of_stack = stack.pop()
44+
input_element = (input_symbol, top_of_stack)
45+
processed_sequance.append(input_element)
46+
47+
papni_data.append((processed_sequance, label))
48+
49+
# instantiate and run PAPNI as base RPNI with stack-aware data
50+
if algorithm != 'edsm':
51+
learned_model = run_RPNI(papni_data, automaton_type='dfa', algorithm=algorithm, print_info=print_info)
52+
else:
53+
learned_model = run_EDSM(papni_data, automaton_type='dfa', print_info=print_info)
54+
55+
# convert intermediate DFA representation to VPA
56+
learned_model = vpa_from_dfa_representation(learned_model, vpa_alphabet)
57+
58+
return learned_model

aalpy/learning_algs/deterministic_passive/RPNI.py

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -56,62 +56,3 @@ def run_RPNI(data, automaton_type, algorithm='gsm',
5656
return learned_model
5757

5858

59-
def run_PAPNI(data, vpa_alphabet, algorithm='edsm', print_info=True):
60-
"""
61-
Run PAPNI, a deterministic passive model learning algorithm of deterministic pushdown automata.
62-
Resulting model conforms to the provided data.
63-
64-
Args:
65-
66-
data: sequence of input sequences and corresponding label. Eg. [[(i1,i2,i3, ...), label], ...]
67-
vpa_alphabet: grouping of alphabet elements to call symbols, return symbols, and internal symbols. Call symbols
68-
push to stack, return symbols pop from stack, and internal symbols do not affect the stack.
69-
algorithm: either 'gsm' for classic RPNI or 'edsm' for evidence driven state merging variant of RPNI
70-
GSM is much faster and less resource intensive.
71-
print_info: print learning progress and runtime information
72-
73-
Returns:
74-
75-
VPA conforming to the data, or None if data is non-deterministic.
76-
"""
77-
from aalpy.utils import is_balanced
78-
from aalpy.automata.Vpa import vpa_from_dfa_representation
79-
from aalpy.learning_algs import run_EDSM
80-
81-
assert algorithm in {'gsm', 'classic', 'edsm'}
82-
83-
# preprocess input sequences to keep track of stack
84-
papni_data = []
85-
for input_seq, label in data:
86-
# if input sequance is not balanced we do not consider it (it would lead to error state anyway)
87-
if not is_balanced(input_seq, vpa_alphabet):
88-
continue
89-
90-
# for each sequance keep track of the stack, and when pop/return element is observed encode it along with the
91-
# current top of stack. This keeps track of stack during execution
92-
processed_sequance = []
93-
stack = []
94-
95-
for input_symbol in input_seq:
96-
input_element = input_symbol
97-
# if call/push symbol push to stack
98-
if input_symbol in vpa_alphabet.call_alphabet:
99-
stack.append(input_symbol)
100-
# if return/pop symbol pop from stack and add it to the input data
101-
if input_symbol in vpa_alphabet.return_alphabet:
102-
top_of_stack = stack.pop()
103-
input_element = (input_symbol, top_of_stack)
104-
processed_sequance.append(input_element)
105-
106-
papni_data.append((processed_sequance, label))
107-
108-
# instantiate and run PAPNI as base RPNI with stack-aware data
109-
if algorithm != 'edsm':
110-
learned_model = run_RPNI(papni_data, automaton_type='dfa', algorithm=algorithm, print_info=print_info)
111-
else:
112-
learned_model = run_EDSM(papni_data, automaton_type='dfa', print_info=print_info)
113-
114-
# convert intermediate DFA representation to VPA
115-
learned_model = vpa_from_dfa_representation(learned_model, vpa_alphabet)
116-
117-
return learned_model

0 commit comments

Comments
 (0)