Commit 3b1555f4 authored by Michele Volpato's avatar Michele Volpato

more specific definition: moved input check inside entries

parent 28d804a9
......@@ -399,7 +399,7 @@ class LearningAlgorithm:
hyp.getChaosDelta())
return hyp
# Get all labels enabled after row
# Get all labels possibly enabled after row
def _getAllLabels(self, row, outputs):
enabledInputs = self._teacher.getInputAlphabet()
enabledOutputs = self._teacher.getOutputAlphabet()
......
......@@ -52,18 +52,21 @@ class Table:
# _rows also contains empty trace
self._rows = set()
self._rows.add(())
for label in self._possibleInputs((), None):
for label in self._possibleInputs(()):
self._rows.add(tuple(label))
# Define the top part of the table (for closedness)
self._rowsInS = set()
# Empty trace is always in S
self._rowsInS.add(())
# Define S^e
# S^e is [x for x in self._rows - self._rowsInS if x.isDefined()]
# _entries is a dictionary (tuple of actions) -> (set(outputs), set(outputs))
# start with the empty sequence of actions and one letter extensions
self._entries = {():(set(),self._possibleOutputs((), None))}
for label in self._possibleInputs((), None):
self._entries[tuple(label)] = (set(),self._possibleOutputs(tuple(label), None))
self._entries = {():(set(),self._possibleOutputs(()))}
for label in self._possibleInputs(()):
self._entries[tuple(label)] = (set(),self._possibleOutputs(tuple(label)))
# Calculate the preciseness of the table
def preciseness(self):
......@@ -87,7 +90,7 @@ class Table:
# Return True if trace is in the table
def isInRows(self, trace):
return trace in self._rows
return trace in self._rows and self.isDefined(trace)
# Given two rows, check if they belong to the same equivalence class
@d.deprecated
......@@ -210,7 +213,7 @@ class Table:
self._logger.warning("Add one letter extensions: "+ str(row) +" is not in the table.")
else:
outputs, observation = self._entries[row]
for my_input in self._possibleInputs(row, outputs):
for my_input in self._possibleInputs(row):
if self.addOneLetterExtension(row, my_input):
modified = True
for output in outputs:
......@@ -335,7 +338,7 @@ class Table:
enabledRow2.add(self._quiescence)
else:
outputs = self.getOutputs(current[1])
enabledInputs = self._possibleInputs(current[1], outputs)
enabledInputs = self._possibleInputs(current[1])
enabledRow2 = outputs.union(enabledInputs)
for label in enabledRow2:
enabledRow1 = set()
......@@ -345,7 +348,7 @@ class Table:
enabledRow1.add(self._quiescence)
else:
outputs = self.getOutputs(current[0])
enabledInputs = self._possibleInputs(current[0], outputs)
enabledInputs = self._possibleInputs(current[0])
enabledRow1 = outputs.union(enabledInputs)
if label not in enabledRow1:
suffixes = set()
......@@ -443,7 +446,7 @@ class Table:
# get all possible (enabled) labels of row1
outputs = self.getOutputs(row1)
inputs = self._possibleInputs(row1, outputs)
inputs = self._possibleInputs(row1)
labels = inputs.union(outputs)
......@@ -574,7 +577,7 @@ class Table:
# get an empty nonfinal entry
def _emptyEntry(self, trace):
return (set(), self._possibleOutputs(trace, None))
return (set(), self._possibleOutputs(trace))
# get an empty final entry
def _emptyFinalEntry(self, trace):
......@@ -682,7 +685,7 @@ class Table:
if trace in self._entries:
return self._entries[trace][1]
else:
return self._possibleOutputs(trace, None)
return self._possibleOutputs(trace)
# Update an entry in the table. If it does not exist, create it
# observation is the answer of the observation oracle
......@@ -709,7 +712,7 @@ class Table:
# given a trace, query outputPurpose for the outputs that are possibly
# enabled after it
def _possibleOutputs(self, trace, outputs):
def _possibleOutputs(self, trace):
if self._outputPurpose == None:
return self._outputs.union(set((self._quiescence,)))
else:
......@@ -717,7 +720,7 @@ class Table:
# given a trace, query inputPurpose for the inputs that are
# enabled after it
def _possibleInputs(self, trace, outputs):
def _possibleInputs(self, trace):
if self._inputPurpose == None:
return self._inputs
else:
......@@ -741,19 +744,20 @@ class Table:
# Given two rows, check if the former is more specific than the latter
# row1 ⊑ row2 => for each column, row1[column] ⊑ row2[column]
def _moreSpecificRow(self, row1, row2, plus=False):
# First: if they do not enable the same inputs, they are not in such
# a relation TODO: should this check be in moreSpecificEntry instead?
outputs1 = self._entries[th.flatten(row1,self._quiescence)][0]
outputs2 = self._entries[th.flatten(row2,self._quiescence)][0]
inputs1 = self._possibleInputs(th.flatten(row1,self._quiescence), outputs1)
inputs2 = self._possibleInputs(th.flatten(row2,self._quiescence), outputs2)
if inputs1 != inputs2:
return False
# If they enable the same inputs, check each entry.
for column in self._columns:
entry1 = th.flatten(row1 + column, self._quiescence)
entry2 = th.flatten(row2 + column, self._quiescence)
# First: if they do not enable the same inputs, they are not in such
# a relation
inputs1 = self._possibleInputs(entry1)
inputs2 = self._possibleInputs(entry2)
if inputs1 != inputs2:
return False
if entry1 not in self._entries and entry2 not in self._entries:
# for some reason both entries do not exist.
self._logger.warning("Checking relation between "+str(entry1)+ " and "+str(entry2)+": both entries are not defined.")
......
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