Commit 2573e7f7 authored by Michele's avatar Michele

added deprecator, started working on more specific for closedness

parent 3612b6db
......@@ -12,7 +12,7 @@ import helpers.bisimulation as bi
from testing.randomtesting import RandomTester
from systems.iopurpose import InputPurpose, OutputPurpose
logger = logging.getLogger(__name__)
inputs = set(['a','b'])
......@@ -52,7 +52,7 @@ O1 = InputOutputPowerOracle(I1)
outputExpert = OutputPurpose(set(['x','y', quiescence]))
inputExpert = InputPurpose(set(['a','b']))
tester = RandomTester(T1, 10000, 20)
tester = RandomTester(T1, 10000, 50)
currentdir = os.path.dirname(os.path.abspath(
import logging
logged = False
def deprecated(func):
"""This is a decorator which can be used to mark functions
as deprecated. It will result in a warning being emmitted
when the function is used."""
def new_func(*args, **kwargs):
# Log only once for each run
global logged
if not logged:
#warnings.simplefilter('always', DeprecationWarning) #turn off filter
print("Warning: Call to deprecated function {}.".format(func.__name__))
#warnings.warn("Call to deprecated function {}.".format(func.__name__), category=DeprecationWarning, stacklevel=2)
#warnings.simplefilter('default', DeprecationWarning) #reset filter
logged = True
return func(*args, **kwargs)
new_func.__name__ = func.__name__
new_func.__doc__ = func.__doc__
return new_func
......@@ -345,7 +345,7 @@ class LearningAlgorithm:
found = False
# TODO: the method of table called at next line is
# private. Change to public, or add a public version
if self._table._rowEquality(extension, target, chaos):
if self._table._moreSpecificRow(extension, target, chaos):
hyp.addTransition(assignments[row], label,
found = True
......@@ -3,6 +3,7 @@ import os, inspect
from itertools import combinations, product
import logging
import helpers.traces as th
import helpers.deprecator as d
class Table:
......@@ -69,6 +70,7 @@ class Table:
return trace in self._rows
# Given two rows, check if they belong to the same equivalence class
def _rowEquality(self, row1, row2, withObservation=False):
for column in self._columns:
entry1 = th.flatten(row1 + column, self._quiescence)
......@@ -87,14 +89,14 @@ class Table:
return False
return True
def getEquivalenceClasses(self, withObservation=False):
def getEquivalenceClasses(self, plus=False):
# () is always in the equivalence classes
rows = set()
for row in self._rowsInS - set(()):
found = False
for singleRow in rows:
if self._rowEquality(row, singleRow, withObservation):
if self._moreSpecificRow(row, singleRow, plus):
found = True
if not found:
......@@ -116,7 +118,7 @@ class Table:
found = False
# search in S
for rowInS in self._rowsInS:
if self._rowEquality(row, rowInS, True):
if self._moreSpecificRow(rowInS, row, True):
# Found a match, exit
found = True
......@@ -124,7 +126,7 @@ class Table:
# Here is the FIRST closing strategy
if not found:
for newRow in rows:
if self._rowEquality(row, newRow, True):
if self._moreSpecificRow(newRow, row, True):
# already added this equivalence class
found = True
......@@ -196,12 +198,12 @@ class Table:
return self.addColumn(newSuffixes, force=True)
# return the length of the longest suffix in columns
def getLengthColumns(self):
length = 0
for item in self._columns:
if len(item) > length:
length = len(item)
return length
# def getLengthColumns(self):
# length = 0
# for item in self._columns:
# if len(item) > length:
# length = len(item)
# return length
def addColumn(self, columns, force=False):
if force:
......@@ -252,8 +254,8 @@ class Table:
for row1 in filter(rowsWithQuiescence, self._rowsInS):
row1Extended = row1 + (self._quiescence,)
# filter for rows in top part of the table that are
# equivalent to row1Extended
equivalentRows = lambda x: lambda y: self._rowEquality(x, y, chaos)
# moreSpecific than row1Extended
equivalentRows = lambda x: lambda y: self._moreSpecificRow(x, y, chaos)
row2 = next(filter(equivalentRows(row1Extended), self._rowsInS))
if row1 == row2:
......@@ -308,6 +310,8 @@ class Table:
# the first entry is emptyEntry.
# In this case (it can only be an input) we
# send the input to chaotic_delta
# Old code, prior to _moreSpecificRow
if self._entries[current[0] + (label,)] == self._emptyEntry(current[0] + (label,)):
newRow1 = "chaos_quiescence"
......@@ -365,12 +369,12 @@ class Table:
newColumns = set()
for row1, row2 in combi:
# If the rows are in the same equivalence class
if self._rowEquality(row1, row2, chaos):
if self._moreSpecificRow(row1, row2, chaos):
for label in labels:
rowExt1 = row1 + (label,)
rowExt2 = row2 + (label,)
if rowExt1 in self._rows and rowExt2 in self._rows:
# I could call self._rowEquality() but then
# I could call self._moreSpecificRow() but then
# I need to iterate again to find the suffix.
# It is better to do it directly.
for column in self._columns:
......@@ -396,7 +400,7 @@ class Table:
if newColumns:
# TODO: only one suffix per round, ok?
if newColumns:
......@@ -580,6 +584,29 @@ class Table:
return self._inputPurpose.getEnabled(trace)
# Given two entries, check if the former is more specific than the latter
def _moreSpecificEntry(self, entry1, entry2, plus):
if not plus:
#return entry1 == entry2
return entry2[0].issubset(entry1[0])
#return entry1[0] == entry2[0]
return (entry2[0].issubset(entry1[0]) and entry1[1].issubset(entry2[1]))
# Given two rows, check if the former is more specific than the latter
def _moreSpecificRow(self, row1, row2, plus=False):
for column in self._columns:
entry1 = th.flatten(row1 + column, self._quiescence)
entry2 = th.flatten(row2 + column, self._quiescence)
if entry1 not in self._entries and entry2 not in self._entries:
return True
elif entry1 not in self._entries or entry2 not in self._entries:
return False
if not self._moreSpecificEntry(self._entries[entry1],
self._entries[entry2], plus):
return False
return True
# Print table, for test
def printTable(self, path=None, prefix=""):
if path == None:
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment