Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
Alnos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
Operations
Operations
Incidents
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Michele Volpato
Alnos
Commits
7c2e3881
Commit
7c2e3881
authored
Nov 26, 2015
by
Michele
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
removed debug code. Working on learning.py
parent
e388a4c6
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
42 additions
and
69 deletions
+42
-69
learning/learning.py
learning/learning.py
+39
-65
learning/observationtable.py
learning/observationtable.py
+3
-4
No files found.
learning/learning.py
View file @
7c2e3881
...
@@ -81,19 +81,16 @@ class LearningAlgorithm:
...
@@ -81,19 +81,16 @@ class LearningAlgorithm:
# cannot force it to happen.
# cannot force it to happen.
def
updateTable
(
self
):
def
updateTable
(
self
):
# First, try to avoid impossible traces: ask observation query
# First, try to avoid impossible traces: ask observation query
print
(
"update"
)
for
trace
in
self
.
_table
.
getObservableTraces
():
for
trace
in
self
.
_table
.
getObservableTraces
():
observedOutputs
=
self
.
_table
.
getOutputs
(
trace
)
observedOutputs
=
self
.
_table
.
getOutputs
(
trace
)
observation
=
self
.
_oracle
.
observation
(
trace
,
observedOutputs
)
observation
=
self
.
_oracle
.
observation
(
trace
,
observedOutputs
)
if
observation
:
if
observation
:
self
.
_table
.
updateEntry
(
trace
,
observation
=
observation
)
self
.
_table
.
updateEntry
(
trace
,
observation
=
observation
)
print
(
"done observable"
)
# For all traces for which we did not observed all possible outputs
# For all traces for which we did not observed all possible outputs
oTraces
=
self
.
_table
.
getObservableTraces
()
oTraces
=
self
.
_table
.
getObservableTraces
()
trie
=
th
.
make_trie
(
oTraces
)
trie
=
th
.
make_trie
(
oTraces
)
print
(
"asking "
+
str
(
len
(
oTraces
))
+
" membership queries"
)
# Until we tried K times with no results, where K is the number of
# Until we tried K times with no results, where K is the number of
# observable traces times the number of outputs (including quiescence)
# observable traces times the number of outputs (including quiescence)
K
=
len
(
oTraces
)
*
35
# (len(self._teacher.getOutputAlphabet()) + 1) # TODO comment from *
K
=
len
(
oTraces
)
*
35
# (len(self._teacher.getOutputAlphabet()) + 1) # TODO comment from *
...
@@ -264,11 +261,15 @@ class LearningAlgorithm:
...
@@ -264,11 +261,15 @@ class LearningAlgorithm:
def
stabilizeTable
(
self
):
def
stabilizeTable
(
self
):
# While nothing changes, keep closing and consistent the table
# While nothing changes, keep closing and making the table consistent
print
(
"Searching closing"
)
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
if
not
closingRows
:
if
self
.
_makeConsistent
():
self
.
updateTable
()
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
while
closingRows
:
while
closingRows
:
print
(
"Not closed"
)
self
.
_logger
.
debug
(
"Table is not closed"
)
self
.
_logger
.
debug
(
"Table is not closed"
)
self
.
_logger
.
debug
(
closingRows
)
self
.
_logger
.
debug
(
closingRows
)
self
.
_table
.
promote
(
closingRows
)
self
.
_table
.
promote
(
closingRows
)
...
@@ -281,49 +282,23 @@ class LearningAlgorithm:
...
@@ -281,49 +282,23 @@ class LearningAlgorithm:
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
if
not
closingRows
:
if
not
closingRows
:
print
(
"Searching consistent"
)
if
self
.
_makeConsistent
():
consistentCheck
=
self
.
_table
.
isNotGloballyConsistent
()
# Table is closed, check for consistency
if
consistentCheck
:
print
(
"Not consistent"
)
self
.
_logger
.
debug
(
"Table is not consistent"
)
self
.
_logger
.
debug
(
consistentCheck
)
self
.
_table
.
addColumn
(
consistentCheck
,
force
=
True
)
if
self
.
_logger
.
isEnabledFor
(
logging
.
DEBUG
):
self
.
_table
.
printTable
(
prefix
=
"_i_"
)
self
.
updateTable
()
self
.
updateTable
()
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
#
def
_makeConsistent
(
self
):
# while closingRows or consistentCheck:
consistentCheck
=
self
.
_table
.
isNotGloballyConsistent
()
# while closingRows:
# Table is closed, check for consistency
# print("Not closed")
if
consistentCheck
:
# self._logger.debug("Table is not closed")
self
.
_logger
.
debug
(
"Table is not consistent"
)
# self._logger.debug(closingRows)
self
.
_logger
.
debug
(
consistentCheck
)
# self._table.promote(closingRows)
self
.
_table
.
addColumn
(
consistentCheck
,
force
=
True
)
# # After promoting one should check if some one letter
if
self
.
_logger
.
isEnabledFor
(
logging
.
DEBUG
):
# # extensions should also be added
self
.
_table
.
printTable
(
prefix
=
"_i_"
)
# self._table.addOneLetterExtensions(closingRows)
return
True
# if self._logger.isEnabledFor(logging.DEBUG):
else
:
# self._table.printTable(prefix="_c_")
return
False
# self.updateTable()
# closingRows = self._table.isNotGloballyClosed()
# consistentCheck = self._table.isNotGloballyConsistent()
# # Table is closed, check for consistency
# if consistentCheck:
# print("Not consistent")
# self._logger.debug("Table is not consistent")
# self._logger.debug(consistentCheck)
# self._table.addColumn(consistentCheck, force=True)
# if self._logger.isEnabledFor(logging.DEBUG):
# self._table.printTable(prefix="_i_")
# # TODO: is an update needed here? in theory, when I encounter
# # an inconsistency, by adding a column, the interesting row
# # will immediately make the table not closed, no need of
# # update, right?
# #self.updateTable()
# closingRows = self._table.isNotGloballyClosed()
# consistentCheck = self._table.isNotGloballyConsistent()
def
getHypothesis
(
self
,
chaos
=
False
):
def
getHypothesis
(
self
,
chaos
=
False
):
# If table is not closed, ERROR
# If table is not closed, ERROR
...
@@ -339,16 +314,26 @@ class LearningAlgorithm:
...
@@ -339,16 +314,26 @@ class LearningAlgorithm:
chaos
)
chaos
)
# assign to each equivalence class a state number
# assign to each equivalence class a state number
# start with equivalence class of empty trace to 0
# start with equivalence class of empty trace to 0
assignments
=
{():
0
}
# TODO: is () always the representative of an equivalence class?
# NO
rowForEmpty
=
()
# search for the representative for ()
for
row
in
rows
:
# TODO: the method of table called at next line is
# private. Change to public, or add a public version
if
self
.
_table
.
_moreSpecificRow
(
row
,
rowForEmpty
,
chaos
):
rowForEmpty
=
row
break
assignments
=
{
rowForEmpty
:
0
}
count
=
1
count
=
1
for
row
in
rows
:
for
row
in
rows
:
if
row
!=
()
:
if
row
!=
rowForEmpty
:
assignments
[
row
]
=
count
assignments
[
row
]
=
count
count
=
count
+
1
count
=
count
+
1
# add transitions
# add transitions
for
row
in
rows
:
for
row
in
rows
:
# TODO reduce allLabels set, use outputExpert
enabledOuptuts
=
self
.
_table
.
getOutputs
(
row
)
enabledOuptuts
=
self
.
_table
.
getOutputs
(
row
)
allLabels
=
self
.
_getAllLabels
(
row
,
enabledOuptuts
)
allLabels
=
self
.
_getAllLabels
(
row
,
enabledOuptuts
)
...
@@ -356,16 +341,15 @@ class LearningAlgorithm:
...
@@ -356,16 +341,15 @@ class LearningAlgorithm:
# create row and search it in the table
# create row and search it in the table
extension
=
row
+
(
label
,)
extension
=
row
+
(
label
,)
if
self
.
_table
.
isInRows
(
extension
):
if
self
.
_table
.
isInRows
(
extension
):
found
=
False
for
target
in
rows
:
for
target
in
rows
:
found
=
False
# TODO: the method of table called at next line is
# TODO: the method of table called at next line is
# private. Change to public, or add a public version
# private. Change to public, or add a public version
if
self
.
_table
.
_moreSpecificRow
(
extension
,
target
,
chaos
):
if
self
.
_table
.
_moreSpecificRow
(
target
,
extension
,
chaos
):
hyp
.
addTransition
(
assignments
[
row
],
label
,
hyp
.
addTransition
(
assignments
[
row
],
label
,
assignments
[
target
])
assignments
[
target
])
found
=
True
found
=
True
break
# do not break here, for hPlus we add nondeterminism here
if
not
found
:
if
not
found
:
self
.
_logger
.
warning
(
"Chaotic behaviour"
)
self
.
_logger
.
warning
(
"Chaotic behaviour"
)
# Either the table is not closed, or
# Either the table is not closed, or
...
@@ -377,7 +361,7 @@ class LearningAlgorithm:
...
@@ -377,7 +361,7 @@ class LearningAlgorithm:
if
label
in
self
.
_teacher
.
getInputAlphabet
():
if
label
in
self
.
_teacher
.
getInputAlphabet
():
hyp
.
addTransition
(
assignments
[
row
],
label
,
hyp
.
addTransition
(
assignments
[
row
],
label
,
hyp
.
getChaosDelta
())
hyp
.
getChaosDelta
())
# TODO: getPossibleOutputs is deprecated
elif
label
in
self
.
_table
.
getPossibleOutputs
(
row
):
elif
label
in
self
.
_table
.
getPossibleOutputs
(
row
):
hyp
.
addTransition
(
assignments
[
row
],
label
,
hyp
.
addTransition
(
assignments
[
row
],
label
,
hyp
.
getChaos
())
hyp
.
getChaos
())
...
@@ -439,37 +423,27 @@ class LearningAlgorithm:
...
@@ -439,37 +423,27 @@ class LearningAlgorithm:
self
.
_currentLoop
=
self
.
_currentLoop
+
1
self
.
_currentLoop
=
self
.
_currentLoop
+
1
self
.
_logger
.
info
(
"Learning loop number "
+
str
(
self
.
_currentLoop
))
self
.
_logger
.
info
(
"Learning loop number "
+
str
(
self
.
_currentLoop
))
# Fill the table and make it closed and consistent
# Fill the table and make it closed and consistent
print
(
"Updating"
)
self
.
updateTable
()
self
.
updateTable
()
# TODO learning sometimes stops here!
print
(
"Stabilizing"
)
self
.
stabilizeTable
()
self
.
stabilizeTable
()
print
(
"Stabilized"
)
# Is the table quiescence reducible? If not make it so and
# Is the table quiescence reducible? If not make it so and
# then fill it again, make it closed and consitent
# then fill it again, make it closed and consitent
print
(
"Reducing"
)
newSuffixes
=
self
.
_table
.
isNotQuiescenceReducible
()
newSuffixes
=
self
.
_table
.
isNotQuiescenceReducible
()
while
(
newSuffixes
or
not
self
.
_table
.
isStable
()):
while
(
newSuffixes
or
not
self
.
_table
.
isStable
()):
print
(
"Something to reduce"
)
if
newSuffixes
:
if
newSuffixes
:
self
.
_logger
.
debug
(
"Table is not quiescence reducible"
)
self
.
_logger
.
debug
(
"Table is not quiescence reducible"
)
self
.
_logger
.
debug
(
newSuffixes
)
self
.
_logger
.
debug
(
newSuffixes
)
if
self
.
_table
.
addColumn
(
newSuffixes
,
force
=
True
):
if
self
.
_table
.
addColumn
(
newSuffixes
,
force
=
True
):
if
self
.
_logger
.
isEnabledFor
(
logging
.
DEBUG
):
if
self
.
_logger
.
isEnabledFor
(
logging
.
DEBUG
):
self
.
_table
.
printTable
(
prefix
=
"_Q_"
)
self
.
_table
.
printTable
(
prefix
=
"_Q_"
)
print
(
"Update in reduce"
)
self
.
updateTable
()
self
.
updateTable
()
print
(
"Stabilize after reducing"
)
self
.
stabilizeTable
()
self
.
stabilizeTable
()
print
(
"Reducing again"
)
newSuffixes
=
self
.
_table
.
isNotQuiescenceReducible
()
newSuffixes
=
self
.
_table
.
isNotQuiescenceReducible
()
print
(
"Done reducing"
)
self
.
_hMinus
=
self
.
getHypothesis
()
self
.
_hMinus
=
self
.
getHypothesis
()
# If there are no observable traces, hMinus == hPlus
# If there are no observable traces, hMinus == hPlus
if
self
.
_table
.
getObservableTraces
()
!=
set
():
if
self
.
_table
.
getObservableTraces
()
!=
set
():
self
.
_hPlus
=
self
.
getHypothesis
(
chaos
=
True
)
self
.
_hPlus
=
self
.
getHypothesis
(
chaos
=
True
)
else
:
else
:
self
.
_hPlus
=
self
.
_hMinus
self
.
_hPlus
=
self
.
_hMinus
print
(
"Hyp created"
)
if
self
.
_printPath
!=
None
:
if
self
.
_printPath
!=
None
:
self
.
generateDOT
(
path
=
self
.
_printPath
)
self
.
generateDOT
(
path
=
self
.
_printPath
)
...
...
learning/observationtable.py
View file @
7c2e3881
...
@@ -675,11 +675,10 @@ class Table:
...
@@ -675,11 +675,10 @@ class Table:
return
outputs
return
outputs
# Return the set of outputs that can be observed after trace
# Return the set of outputs that can be observed after trace
# TODO: not clear the purpose of this method. rename?
# Return the second set.
@
d
.
deprecated
def
getPossibleOutputs
(
self
,
trace
):
def
getPossibleOutputs
(
self
,
trace
):
if
trace
in
self
.
_entries
and
self
.
_entries
[
trace
][
1
]
:
if
trace
in
self
.
_entries
:
return
self
.
_entries
[
trace
][
0
]
return
self
.
_entries
[
trace
][
1
]
else
:
else
:
return
self
.
_possibleOutputs
(
trace
,
None
)
return
self
.
_possibleOutputs
(
trace
,
None
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment