def test_parse_and_execute_substitution(self): pli = ProblogInterface() pli.append('implementation(r1, "x.v = 2 * a.v").') # parse s = pli.parse_substitution( "substitution(x, [function(x,r1,[a]), a1] )") self.assertEqual(s.vout.name, 'x') self.assertEqual(set([v.name for v in s.vin]), set(['a1'])) self.assertEqual(len(s), 2) # execute a1 = Itom('a1', 1) result = s.execute([a1]) self.assertEqual(result['x'].v, 2) # ambiguous implementation pli.append('implementation(r1, "x.v = 4 * a.v").') with self.assertRaises(AmbiguousImplementation): s = pli.parse_substitution( "substitution(x, [function(x,r1,[a]), a1] )") # no implementation pli.reset() with self.assertRaises(Exception): s = pli.parse_substitution( "substitution(x, [function(x,r1,[a]), a1] )") # any string as itom identifiers pli.reset() b = Itom('/p2os/sonar', [1, 2, 3]) pli.append('implementation(min, "a.v = min(b.v)").') s = pli.parse_substitution( "substitution(a, [function(a, min, [b]), {}]).".format('"' + b.name + '"')) v = s.execute([b]) self.assertEqual(v['a'].v, 1)
def test_availability(self): a1 = Itom('a1', 0, variable='a') a2 = Itom('a2', 1, variable='a') b1 = Itom('b1', 2.1, variable='b') itoms = Itoms([a1, a2, b1]) av = itoms.availability self.assertEqual(len(av.keys()), 2) self.assertEqual(len(av['a']), 2) self.assertTrue('a1' in [itom.name for itom in av['a']]) self.assertEqual(len(av['b']), 1)
def test_execute(self): s = Substitution([self.__f_add, self.__f_mult]) b = Itom('b', 1) c = Itom('c', 2) itoms = Itoms(list=[b, c]) variables = s.execute(itoms) self.assertEqual(variables['d'].v, 6) # function names not unique s = Substitution([self.__f_add, self.__f_add2]) variables = s.execute([b, c]) self.assertEqual(variables['a'].v, 3)
def __collect_substitutions(self, itoms=[]): """Find relations from variables (given itoms) to domain.""" program = "\n" if "itomsOf" not in self.__pli.program and len(itoms) > 0: # be sure itoms is of the right type 'Itoms' itoms = Itoms(itoms) # append available itoms to program with "itomsOf(variable,[itom1,..])" for variable, il in itoms.availability.items(): assert variable is not None and variable != "" names = [i.name for i in il] program += "itomsOf({},[{}]).\n".format(variable, ','.join(names)) program += "\n" if len(itoms) > 0: assert "itomsOf" in program or "itomsOf" in self.__pli.program # get all valid substitutions for the domain # -> query problog knowledge base program += "query(substitution({},S)).".format(self.__domain) result = self.__pli.evaluate(program) S = [] for r in result.keys(): s = self.__pli.parse_substitution(str(r)) S.append(s) if len(itoms) == 0: # set itoms used (default value) for s in S: for v in s.vin: self.__itoms[v.name] = Itom(v.name, 0.0, variable=v.name) return S
def test_execute_with_interval(self): f = Function('a', ['b', 'c'], "a.v = b.v + c.v", name="add") b = Itom('b', interval([0.5, 1.5])) c = Itom('c', interval([1, 3])) o = f.execute(Itoms([b, c])) self.assertEqual(o['a'].v, interval([1.5, 4.5])) # mix interval arithmetic with scalars b = Itom('b', 1) o = f.execute(Itoms([b, c])) self.assertEqual(o['a'].v, interval([2, 4])) # timestamps are intervals code = "a.v = b.v + c.v" + "\n" + "a.t = b.t & c.t" f = Function('a', ['b', 'c'], code, name="add") b = Itom('b', 1, interval([0.1, 0.2])) c = Itom('c', 2, interval([0.15, 0.25])) o = f.execute(Itoms([b, c])) self.assertEqual(o['a'].v, 3) self.assertEqual(o['a'].t, interval([0.15, 0.2]))
def test_implementation_multiline(self): self.__pli.reset() self.__pli.load("test/test_py-implementation-multiline.pl") result = self.__pli.evaluate("query(implementation(r1, X)).") relation, code = self.__pli.parse_implementation(list(result)[0]) self.assertEqual(relation, "r1") # create function to execute f = Function('a', 'b', code, name='r1') itoms = f.execute(Itoms([Itom('b', 1, timestamp=0, variable='b')])) self.assertEqual(itoms['a'].v, 2) self.assertEqual(itoms['a'].t, 0) # execute through substitution S = self.__get_substitutions("query(substitution(a,S)).") itoms = Itoms([Itom('b1', 1, timestamp=0, variable='b')]) outputs = self.__execute_substitutions(S, itoms) s = list(S)[0] self.assertEqual(outputs[s]['a'].v, 2) self.assertEqual(outputs[s]['a'].t, 0)
def test_monitor_with_delay_model(self): m = Monitor("test/test_py-monitor-delay-simple.pl", 'x') # delayed step function (x1 is slower than a1) i0 = Itoms([Itom('a1', 0, variable='a'), Itom('x1', 0, variable='x')]) i1 = Itoms([Itom('a1', 1, variable='a'), Itom('x1', 0, variable='x')]) i2 = Itoms([Itom('a1', 1, variable='a'), Itom('x1', 1, variable='x')]) failed = m.monitor(i0) self.assertEqual(failed, None) failed = m.monitor(i0) self.assertEqual(failed, None) failed = m.monitor(i1) self.assertEqual(failed, None) # x1 (value is still 0) doesn't follow a1 (v=1) failed = m.monitor(i1) self.assertNotEqual(failed, None) failed = m.monitor(i2) self.assertEqual(failed, None) # delay = 2 timesteps m = Monitor("test/test_py-monitor-delay-general.pl", 'x') failed = m.monitor(i0) self.assertEqual(failed, None) failed = m.monitor(i0) self.assertEqual(failed, None) failed = m.monitor(i1) self.assertEqual(failed, None) failed = m.monitor(i1) self.assertEqual(failed, None) failed = m.monitor(i1) self.assertNotEqual(failed, None) failed = m.monitor(i2) self.assertEqual(failed, None)
def test_init_itoms(self): empty = Itoms() a = Itom('a', 0) b = Itom('b', 1, variable='b') c = Itom('c', 2.1) l = Itoms(list=[a, b, c]) self.assertEqual(len(l), 3) self.assertEqual(l['a'].v, 0) l = Itoms([a, b, c]) self.assertEqual(len(l), 3) self.assertEqual(l['b'].v, 1) # try different initial iterables and keys l = Itoms({1: a, 2: b, 3: c}) self.assertEqual(len(l), 3) self.assertEqual(l[1], a) l = Itoms(set([a, b, c])) self.assertEqual(len(l), 3) self.assertTrue(c in l.values()) # start from empty dict l = Itoms() l['av'] = a self.assertEqual(len(l), 1) self.assertEqual(l['av'], a)
def test_init_itom(self): a = Itom('a', 0) self.assertEqual(a.v, 0) self.assertEqual(a.t, None) a.v = 1 a.t = 0 self.assertEqual(a.v, 1) self.assertEqual(a.t, 0) a.v = 0 self.assertEqual(a.v, 0) self.assertEqual(a.t, None) b = Itom('b1', 1, variable='b') self.assertEqual(b.variable, 'b') c = Itom('c', 2.1) self.assertAlmostEqual(c.v, 2.1)
def test_preserve_vars(self): # note: local variables can only preserved when # - the function is *not* wrapped # The variables are created as local variables of the function # (global c does not work here -- there is no global variable c). f = Function('a', ['b'], "try:\n" \ " c = c + 1\n" \ "except:\n" " c = 0\n" \ "a.v = b.v + c\n", name="inc", wrap=False) b = Itom('b', 1) o = f.execute([b]) self.assertEqual(o['a'].v, 1) o = f.execute([b]) self.assertEqual(o['a'].v, 2)
def test_implementation_simple(self): self.__pli.load("test/test_py-implementation-simple.pl") S = self.__get_substitutions("query(substitution(x,S)).") # create some dummy data x1 = Itom('x1', 2, variable='x') x2 = Itom('x2', 2, variable='x') a1 = Itom('a1', 1, variable='a') b1 = Itom('b1', 1, variable='b') c1 = Itom('c1', 1, variable='c') d1 = Itom('d1', 4, variable='d') itoms = Itoms([x1, x2, a1, b1, c1, d1]) # execute substitutions outputs = self.__execute_substitutions(S, itoms) # check for output_itoms in outputs.values(): self.assertAlmostEqual(output_itoms['x'].v, 2)
def test_time_uncertainty(self): m = Monitor("test/test_py-monitor-simple.pl", 'x') # itoms with uncertainties in time iok = Itoms([ Itom('x1', interval([9, 11]), timestamp=interval([0.1, 0.2]), variable='x'), Itom('a1', interval([5, 6]), timestamp=interval([0.15, 0.25]), variable='a'), Itom('b1', interval([4, 8]), timestamp=interval([0.1, 0.3]), variable='b'), ]) failed = m.monitor(iok) self.assertEqual(failed, None) # some itoms timestamps do not overlap ilate = Itoms([ Itom('x1', interval([9, 11]), timestamp=interval([0.0, 0.09]), variable='x'), Itom('a1', interval([5, 6]), timestamp=interval([0.15, 0.25]), variable='a'), Itom('b1', interval([4, 8]), timestamp=interval([0.1, 0.3]), variable='b'), ]) failed = m.monitor(ilate) self.assertEqual(failed, None)
def test_timestamp_model(self): m = Monitor("test/test_py-monitor-timestamp-simple.pl", 'c') self.assertEqual(m.buffer_size, 1) a1 = Itom('a1', 1, interval([0.11, 0.21]), variable='a') b1 = Itom('b1', 2, interval([0.12, 0.22]), variable='b') c1 = Itom('c1', 3, interval([0.05, 0.15]), variable='c') c2 = Itom('c2', 3, interval([0.14, 0.24]), variable='c') failed = m.monitor(Itoms([a1, b1, c1, c2])) self.assertEqual(failed, None) # wrong value, however time stamp do not overlap -> won't be used for comparison c1_late = Itom('c1', 0, interval([0.0, 0.04]), variable='c') failed = m.monitor(Itoms([a1, b1, c1_late, c2])) self.assertEqual(failed, None) # monitor shall compensate late itoms -> increase buffer size m = Monitor("test/test_py-monitor-timestamp-simple.pl", 'c', buffer_size=2) self.assertEqual(m.buffer_size, 2) failed = m.monitor(Itoms([c1, c2])) failed = m.monitor(Itoms([c1_late, c2])) # another late value but wrong itom arrives c2_wrong = Itom('c2', 1, interval([0.0, 0.03]), variable='c') failed = m.monitor(Itoms([c1, c2_wrong])) self.assertNotEqual(failed, None)
def test_interval(self): a = Itom('a', interval([0.9, 1.1])) self.assertTrue(1 in a.v)
# try: data = pd.read_csv(args.csv) except Exception as e: raise SystemExit("Failed to parse csv. {}".format(e)) # get variable/itoms available from column name (header) 'variable:itom' itoms = Itoms() try: for head in data.columns.values: head = head.strip().split(':') v = head[0] i = head[1] # empty value and timestamp for this itom describing the header only itom = Itom(i, None, variable=v, timestamp=None) itoms[itom.name] = itom except Exception as e: raise SystemExit( "Failed to parse column name 'variable:itom'. {}".format(e)) # problog knows the mapping now, so we can change the column names to itoms only # substitution only needs itom names data.columns = itoms.keys() # append available itoms to program with "itomsOf(variable,[itom1,..])" program = "\n" for variable, il in itoms.availability.items(): names = [itom.name for itom in il] program += "itomsOf({},[{}]).\n".format(variable, ','.join(names))
description="""Save perfect/equal itoms to pickle object file.""") parser.add_argument("-o", "--output", type=str, default="generated.obj", help="""Output (pickle object file for run.py).""") args = parser.parse_args() # # generate some perfect (equal and on time) itoms # t_reception = np.arange(0.5 * 1e9, 15 * 1e9, 1e9) # in nsec similar to ROS timestamps itoms = [(tr + n * 0.15 * 1e9, Itom(s, 1.8 + (-0.5) / 10 * tr / 1e9, tr + n * 0.15 * 1e9, signal2variable[s])) for tr in t_reception for n, s in enumerate(signals)] print "[generate itoms] number of itoms: {}".format(len(itoms)) # # dump data # data = { 'manipulated': False, 'itoms': itoms, 'signals': signals, 'faults': [], } with open(args.output, 'wb') as f:
def test_execute(self): f = Function('a', ['b', 'c'], "a.v = b.v + c.v", name="add") a = Itom('a', 0) b = Itom('b', 1) c = Itom('c', 2) itoms = Itoms([a, b, c]) v = f.execute(itoms) self.assertAlmostEqual(v['a'].v, 3) b.v = 4 c.v = 2 v = f.execute(itoms) self.assertAlmostEqual(v['a'].v, 6) a.v = 0 b.v = 5 c.v = 5 v = f.execute(itoms) self.assertAlmostEqual(v['a'].v, 10) with self.assertRaises(Exception): f.execute({a.name: a}) with self.assertRaises(Exception): f.execute({b.name: b}) # test execution without wrapping the code in a function f = Function('a', ['b', 'c'], "a.v = b.v + c.v", name="add", wrap=False) b.v = 1 c.v = 2 v = f.execute(itoms) self.assertAlmostEqual(v['a'].v, 3) # function setting timestamp f = Function('a', ['b', 'c'], "a.v = b.v + c.v; a.t = max(b.t, c.t)", name="add") b.t = 0 c.t = 1 v = f.execute(itoms) self.assertEqual(v['a'].t, 1) # test execution with non-Python-identifiers as variables b = Itom('0b', 1) c = Itom('1c', 2) f = Function('a', [b.name, c.name], "a.v = {}.v + {}.v".format(b.codename, c.codename)) v = f.execute(Itoms([b, c])) self.assertAlmostEqual(v['a'].v, 3) # function with lists (e.g., ROS itoms representing point clouds) sonar = Itom('/p2os/sonar', [1, 3, 4]) f = Function('dmin', [sonar.name], "dmin.v = min({}.v)".format(sonar.codename)) v = f.execute(Itoms([sonar])) self.assertAlmostEqual(v['dmin'].v, 1)
def setUp(self): self.__itoms1 = Itoms([ Itom('x1', 10, variable='x'), Itom('x2', 10.01, variable='x'), Itom('a1', 5, variable='a'), Itom('b1', 5.1, variable='b'), Itom('c1', 4.95, variable='c'), Itom('d1', 19, variable='d'), ]) # no error (all intervals intersect in the common domain) self.__itoms2 = Itoms([ Itom('x1', interval([9, 11]), variable='x'), Itom('a1', interval([4.9, 5.1]), variable='a'), Itom('d1', interval([19.5, 20.5]), variable='d'), ]) # error (d1) self.__itoms2_err = Itoms([ Itom('x1', interval([9, 11]), variable='x'), Itom('a1', interval([4.9, 5.1]), variable='a'), Itom('d1', interval([23, 25]), variable='d'), # error because: 9..11 does not inersect with 11.5..12.5 ])