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
Show 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:
# cannot force it to happen.
def
updateTable
(
self
):
# First, try to avoid impossible traces: ask observation query
print
(
"update"
)
for
trace
in
self
.
_table
.
getObservableTraces
():
observedOutputs
=
self
.
_table
.
getOutputs
(
trace
)
observation
=
self
.
_oracle
.
observation
(
trace
,
observedOutputs
)
if
observation
:
self
.
_table
.
updateEntry
(
trace
,
observation
=
observation
)
print
(
"done observable"
)
# For all traces for which we did not observed all possible outputs
oTraces
=
self
.
_table
.
getObservableTraces
()
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
# observable traces times the number of outputs (including quiescence)
K
=
len
(
oTraces
)
*
35
# (len(self._teacher.getOutputAlphabet()) + 1) # TODO comment from *
...
...
@@ -264,11 +261,15 @@ class LearningAlgorithm:
def
stabilizeTable
(
self
):
# While nothing changes, keep closing and consistent the table
print
(
"Searching closing"
)
# While nothing changes, keep closing and making the table consistent
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
if
not
closingRows
:
if
self
.
_makeConsistent
():
self
.
updateTable
()
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
while
closingRows
:
print
(
"Not closed"
)
self
.
_logger
.
debug
(
"Table is not closed"
)
self
.
_logger
.
debug
(
closingRows
)
self
.
_table
.
promote
(
closingRows
)
...
...
@@ -281,49 +282,23 @@ class LearningAlgorithm:
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
if
not
closingRows
:
print
(
"Searching consistent"
)
if
self
.
_makeConsistent
():
self
.
updateTable
()
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
def
_makeConsistent
(
self
):
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
()
closingRows
=
self
.
_table
.
isNotGloballyClosed
()
return
True
else
:
return
False
#
# while closingRows or consistentCheck:
# while closingRows:
# print("Not closed")
# self._logger.debug("Table is not closed")
# self._logger.debug(closingRows)
# self._table.promote(closingRows)
# # After promoting one should check if some one letter
# # extensions should also be added
# self._table.addOneLetterExtensions(closingRows)
# if self._logger.isEnabledFor(logging.DEBUG):
# self._table.printTable(prefix="_c_")
# 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
):
# If table is not closed, ERROR
...
...
@@ -339,16 +314,26 @@ class LearningAlgorithm:
chaos
)
# assign to each equivalence class a state number
# 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
for
row
in
rows
:
if
row
!=
()
:
if
row
!=
rowForEmpty
:
assignments
[
row
]
=
count
count
=
count
+
1
# add transitions
for
row
in
rows
:
# TODO reduce allLabels set, use outputExpert
enabledOuptuts
=
self
.
_table
.
getOutputs
(
row
)
allLabels
=
self
.
_getAllLabels
(
row
,
enabledOuptuts
)
...
...
@@ -356,16 +341,15 @@ class LearningAlgorithm:
# create row and search it in the table
extension
=
row
+
(
label
,)
if
self
.
_table
.
isInRows
(
extension
):
for
target
in
rows
:
found
=
False
for
target
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
(
extension
,
target
,
chaos
):
if
self
.
_table
.
_moreSpecificRow
(
target
,
extension
,
chaos
):
hyp
.
addTransition
(
assignments
[
row
],
label
,
assignments
[
target
])
found
=
True
break
# do not break here, for hPlus we add nondeterminism here
if
not
found
:
self
.
_logger
.
warning
(
"Chaotic behaviour"
)
# Either the table is not closed, or
...
...
@@ -377,7 +361,7 @@ class LearningAlgorithm:
if
label
in
self
.
_teacher
.
getInputAlphabet
():
hyp
.
addTransition
(
assignments
[
row
],
label
,
hyp
.
getChaosDelta
())
# TODO: getPossibleOutputs is deprecated
elif
label
in
self
.
_table
.
getPossibleOutputs
(
row
):
hyp
.
addTransition
(
assignments
[
row
],
label
,
hyp
.
getChaos
())
...
...
@@ -439,37 +423,27 @@ class LearningAlgorithm:
self
.
_currentLoop
=
self
.
_currentLoop
+
1
self
.
_logger
.
info
(
"Learning loop number "
+
str
(
self
.
_currentLoop
))
# Fill the table and make it closed and consistent
print
(
"Updating"
)
self
.
updateTable
()
# TODO learning sometimes stops here!
print
(
"Stabilizing"
)
self
.
updateTable
()
self
.
stabilizeTable
()
print
(
"Stabilized"
)
# Is the table quiescence reducible? If not make it so and
# then fill it again, make it closed and consitent
print
(
"Reducing"
)
newSuffixes
=
self
.
_table
.
isNotQuiescenceReducible
()
while
(
newSuffixes
or
not
self
.
_table
.
isStable
()):
print
(
"Something to reduce"
)
if
newSuffixes
:
self
.
_logger
.
debug
(
"Table is not quiescence reducible"
)
self
.
_logger
.
debug
(
newSuffixes
)
if
self
.
_table
.
addColumn
(
newSuffixes
,
force
=
True
):
if
self
.
_logger
.
isEnabledFor
(
logging
.
DEBUG
):
self
.
_table
.
printTable
(
prefix
=
"_Q_"
)
print
(
"Update in reduce"
)
self
.
updateTable
()
print
(
"Stabilize after reducing"
)
self
.
stabilizeTable
()
print
(
"Reducing again"
)
newSuffixes
=
self
.
_table
.
isNotQuiescenceReducible
()
print
(
"Done reducing"
)
self
.
_hMinus
=
self
.
getHypothesis
()
# If there are no observable traces, hMinus == hPlus
if
self
.
_table
.
getObservableTraces
()
!=
set
():
self
.
_hPlus
=
self
.
getHypothesis
(
chaos
=
True
)
else
:
self
.
_hPlus
=
self
.
_hMinus
print
(
"Hyp created"
)
if
self
.
_printPath
!=
None
:
self
.
generateDOT
(
path
=
self
.
_printPath
)
...
...
learning/observationtable.py
View file @
7c2e3881
...
...
@@ -675,11 +675,10 @@ class Table:
return
outputs
# Return the set of outputs that can be observed after trace
# TODO: not clear the purpose of this method. rename?
@
d
.
deprecated
# Return the second set.
def
getPossibleOutputs
(
self
,
trace
):
if
trace
in
self
.
_entries
and
self
.
_entries
[
trace
][
1
]
:
return
self
.
_entries
[
trace
][
0
]
if
trace
in
self
.
_entries
:
return
self
.
_entries
[
trace
][
1
]
else
:
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