def init_table(name, first_row, first_column, row_number, column_number): """ Initialize a table predicate :param name: table name :type name: str :param first_row: first row ID :type first_row: int :param first_column: first column ID :type first_column: int :param row_number: row number :type row_number: int :param column_number: column number :type column_number: int :return: The table Term :rtype: Problog Term """ return Term( "table", Constant("'{}'".format(name)), Constant(first_row), Constant(first_column), Constant(row_number), Constant(column_number), )
def get_array_term(name, index, array): return Term( name, Constant(index), *[ Constant(array[j]) if array[j] is not None else Var("X" + str(j)) for j in range(len(array)) ])
def cell_to_atoms(table_name, header, cell_row, column_type, column_unique_values, cell_value, **kwargs): table_name = unquote(str(table_name)).lower() header = unquote(str(header)).lower() cell_row = unquote(str(cell_row)).lower() column_type = unquote(str(column_type)).lower() cell_value = unquote(str(cell_value)).lower() column_unique_values1 = term2list(column_unique_values) # print(column_unique_values1) row_id = table_name + "_r" + cell_row # result = [Term(header, Constant(row_id), Constant(cell_value))] result = [] result.append((Term("row", Constant(row_id)), 1.0)) if column_type == "string": for unique_value in column_unique_values1: if unquote(unique_value).lower() == cell_value: result.append((Term(header + "_" + cell_value, Constant(row_id)), 1.0)) else: # WIth Probability 0 result.append(( Term( header + "_" + unquote(unique_value).lower(), Constant(row_id), ), 0.0, )) return result
def init_table_cell_type(table_name, row, column, cell_type): """ Initialize a table_cell_type predicate :param table_name: The name of the table containing this header :type table_name: str :param row: The cell row ID :type row: int :param column: The cell column ID :type column: int :param cell_type: The cell type :type cell_type: str :return: The table_cell_type predicate :rtype: Problog term """ return Term( "table_cell_type", Constant("'{}'".format(table_name)), Constant(row), Constant(column), Constant(cell_type), )
def init_cell_transform(row, column, value, transformation_id, p=None): """ Initialize a cell_transform predicate :param row: The cell row ID :type row: int :param column: The cell column ID :type column: int :param value: The cell value :type value: str :param p: The cell probability (optional) :type p: float :return: The cell Term :rtype: Problog Term """ return Term( "cell_transform", Constant(row), Constant(column), Constant(value), Constant(transformation_id), p=p, )
def main(): mod = GDLIIIEngine('./examples/montyhall.gdliii', File_Format.INFIX) res = {} for i in range(0,1000): print(f"Game {i}") #Random initial door choice to begin with moves1 = mod.get_legal_moves()[PLAYER_NAME] mod.set_actions({PLAYER_NAME: choice(moves1)}) mod.update_step() #Second step, can only choose noop mod.set_actions({PLAYER_NAME: mod.get_legal_moves()[PLAYER_NAME][0]}) mod.update_step() #Important step to show game playing capability. Check whether we believe we are currently in a winning state #If yes, then choose noop, if no choose switch (p100,goal100) = mod.query(PLAYER_NAME, Term('goal', Constant(mod.player_to_id(PLAYER_NAME)), Constant('100')))[0] (p0,goal0) = mod.query(PLAYER_NAME, Term('goal', Constant(mod.player_to_id(PLAYER_NAME)), Constant('0')))[0] if (p100 > p0): #Perform Noop if we are more likely to be in the winning state already mod.set_actions({PLAYER_NAME:mod.get_legal_moves()[PLAYER_NAME][0]}) else: #Perform switch if we are likely to be in the losing state mod.set_actions({PLAYER_NAME:mod.get_legal_moves()[PLAYER_NAME][1]}) mod.update_step() # Add a counter to either goal(1,0) if we lost, or goal(1,100) if we won try: res[mod.query(PLAYER_NAME, Term('goal', Constant(mod.player_to_id(PLAYER_NAME)), Var('_')))[0]] += 1 except: res[mod.query(PLAYER_NAME, Term('goal', Constant(mod.player_to_id(PLAYER_NAME)), Var('_')))[0]] = 1 # Go back to beginning of game for i in range(3): mod.undo_step() print(res)
def test_add_rule(self): engine = self.engines['sysadmin'] running = Term('running') c1 = Constant('c1') c2 = Constant('c2') c3 = Constant('c3') r1 = Fluent.create_fluent(running(c1), 1) r2 = Fluent.create_fluent(running(c2), 1) r3 = Fluent.create_fluent(running(c3), 1) head = Term('__s0__') body = ~r1 & ~r2 & ~r3 rule = head << body node = engine.add_rule(head, [~r1, ~r2, ~r3]) self.assertTrue(engine.get_rule(node), rule) head = Term('__s3__') body = r1 & r2 & ~r3 node = engine.add_rule(head, [r1, r2, ~r3]) rule = engine.get_rule(node) self.assertTrue(rule, head << body) head = Term('__s7__') body = r1 & r2 & r3 rule = head << body node = engine.add_rule(head, [r1, r2, r3]) self.assertTrue(engine.get_rule(node), rule)
def add_annotated_disjunction(self, facts, probabilities): """ Add a new annotated disjunction to the program database from a list of `facts` and its `probabilities`. Return a list of choice nodes. :param facts: list of probabilistic facts :type facts: list of problog.logic.Term :param probabilities: list of valid individual probabilities such that the total probability is less than or equal to 1.0 :type probabilities: list of float in [0.0, 1.0] :rtype: list of int """ disjunction = [ f.with_probability(Constant(p)) for f, p in zip(facts, probabilities) ] self._db += AnnotatedDisjunction(heads=disjunction, body=Constant('true')) choices = [] for node, term in enumerate(self._db._ClauseDB__nodes): if str(term).startswith('choice'): choices.append((term, node)) nodes = [] for term in disjunction: term = term.with_probability(None) for choice, node in choices: if term in choice.functor.args: nodes.append(node) return nodes
def parse_constant_str(constant_str: str) -> Constant: if ConstantBuilder.is_int(constant_str): return Constant(int(constant_str)) elif ConstantBuilder.is_float(constant_str): return Constant(float(constant_str)) else: return Term(constant_str)
def get_cell(self, *args): self.update_matrix() if self.__loaded: shape = self.__matrix.shape if len(args) == len(shape) and all(args[i] < shape[i] for i in range(len(args))): return Term("cell", *[Constant(a) for a in args], Constant(self.__matrix[args]))
def test_test(self): model_string = "nn(fc,[X,Y],Z,[0,1]) :: a(X,Y,Z).\nb(X,Y,Z) :- a(X,Y,Z)." fc = FC(10, 2) net = Network(fc, 'fc', lambda a, b, c: Variable(torch.FloatTensor([0.2, 0.8]))) model = Model(model_string, [net]) query = Term('b', Constant("string with 's"), Constant(3), Var('X')) solution = model.solve(query, test=True) print(solution)
def main_loop(model): while(not model.terminal): playerMoves = tuple(model.getLegalMovesForPlayer(Constant(1))) randomMoves = tuple(model.getLegalMovesForPlayer(Constant(0))) model.submitAction(choice(playerMoves), Constant(1)) model.submitAction(choice(randomMoves), Constant(0)) model.applyActionsToModelAndUpdate() #For Monty Hall #print(model.query(Constant(1), Term('car', Var('_')))) #For guessing game print(model.query(Constant(1), Term('num', Var('_'))))
def unify_clause(clause): if isinstance(clause, Clause): head = deepcopy(clause.head) proba = head.probability if proba is None: proba = 1 head.probability = None if not isinstance(proba, Constant): proba = Constant(proba) return [(head, Constant(proba), clause.body)] return []
def test_indirect_evidence(self): model_string = """nn(fc,[X],Y,[0,1,2,3,4,5,6,7,8,9])::digit(X,Y). addition(X,Y,Z) :- digit(X,X2),digit(Y,Y2),Z is X2+Y2.""" #evidence(digit(2,2)).""" #model_string = "nn(fc,[X])::a(X).\nb:-a(0.2).\nc:-b.\nevidence(b)." fc = FC(10, 10) net = Network(fc, 'fc', lambda a, b: Variable(torch.FloatTensor([0.1] * 10))) model = Model(model_string, [net]) query = Term('digit', Constant(2), Constant(2)) #query = Term('addition',Constant(2),Constant(3),Constant(5)) solution = model.solve(query) print(solution)
def test_fluent(self): terms = [ Term('t0'), Term('t1', args=(Constant('c1'), )), Term('t2', args=(Constant('c1'), Constant('c2'))) ] for term in terms: for timestep in range(2): fluent = Fluent.create_fluent(term, timestep) self.assertEqual(fluent.functor, term.functor) self.assertEqual(fluent.arity, term.arity + 1) self.assertEqual(fluent.args[:-1], term.args) self.assertEqual(fluent.args[-1], Constant(timestep))
def rules2scope(hypothesis): result = [Term("predictor", Constant(str(hypothesis) + "."))] rules = hypothesis.to_clauses(hypothesis.target.functor) # First rule is failing rule: don't print it if there are other rules. if len(rules) > 1: rule = hypothesis count = 0 for rule_str in rules[1:]: if "true" in str(rule): text = str(rule).replace("true", "row(A)") else: text = str(rule) + ",row(A)" result.append( Term( "blackbox_rule", Constant(rule.target.functor), Constant(count), Term("'" + text + ".'"), ) ) result.append( Term( "whitebox_rule", Constant(rule.target.functor), Constant(count), *rule.get_literals() ) ) rule = rule.previous count += 1 else: if "true" in str(hypothesis): text = str(hypothesis).replace("true", "row(A)") else: text = str(hypothesis) + ",row(A)" result.append( Term( "blackbox_rule", Constant(hypothesis.target.functor), Constant(0), Term("'" + text + ".'"), ) ) result.append( Term( "whitebox_rule", Constant(hypothesis.target.functor), Constant(0), *hypothesis.get_literals() ) ) return result
def test_action_space(self): reboot = Term('reboot') computers = [Constant('c%i' % i) for i in range(1, 4)] fluents = [reboot(c) for c in computers] fluents.append(reboot(Constant('none'))) actions = ActionSpace(fluents) for i, action in enumerate(actions): self.assertEqual(sum(action.values()), 1) for j, (fluent, value) in enumerate(action.items()): self.assertEqual(fluent, fluents[j]) if j == i: self.assertEqual(value, 1) else: self.assertEqual(value, 0)
def set_actions(self, moves): for (player, action) in moves.items(): if player not in self.player_names: raise Exception("{} is an undefined role".format(player)) self._gdl_rep.submitAction( Term('legal', Constant(self._player_map[player]), action), self._player_map[player])
def recorded(key): db = problog_export.database.get_data(recdb_key, {}) lst = db.get(key) if lst is None: return () else: return [(x.val, Constant(x)) for x in lst]
def get_leaf_node_clause(self, node: TreeNode, previous_conjunction: Term) -> Term: if self.kb_format == KnowledgeBaseFormat.MODELS: # TODO: TEST THIS strategy = node.strategy # type: MLEDeterministicLeafStrategy label_frequencies = strategy.label_frequencies # type: Optional[Dict[Label, float]] goals_with_probabilities = [] for label in label_frequencies.keys(): goal = label.with_probability(label_frequencies[label]) goals_with_probabilities.append(goal) return AnnotatedDisjunction(goals_with_probabilities, previous_conjunction) elif self.kb_format == KnowledgeBaseFormat.KEYS: var = self.prediction_goal.args[self.index] # type: Var strategy = node.strategy # type: MLEDeterministicLeafStrategy label_frequencies = strategy.label_frequencies # type: Optional[Dict[Label, float]] goals_with_probabilities = [] for label in label_frequencies.keys(): substitution = {var.name: label} # type: Dict[str, Term] goal_with_label = apply_substitution_to_term( self.prediction_goal, substitution) # type: Term probability_of_goal = Constant(label_frequencies[label]) goal_with_label.probability = probability_of_goal goals_with_probabilities.append(goal_with_label) return AnnotatedDisjunction(goals_with_probabilities, previous_conjunction) else: raise ValueError("Unexpected value of KnowledgeBaseFormat: " + str(self.kb_format))
def test_state_space(self): running = Term('running') fluents = [ running.with_args(Constant('c%d' % i), Constant(0)) for i in range(1, 4) ] states = StateSpace(fluents) for i, state in enumerate(states): self.assertEqual(len(state), 3) n = 0 for j, (fluent, value) in enumerate(state.items()): self.assertEqual(fluent.functor, 'running') self.assertEqual(fluent.args[0], 'c%d' % (j + 1)) self.assertEqual(fluent.args[-1], 0) n += value * (2**j) self.assertEqual(n, i)
def _process_atom_output(self, atom, body): """Returns tuple ( prob_atom, [ additional clauses ] )""" if isinstance(atom, Or): atoms = atom.to_list() else: atoms = [atom] transforms = defaultdict(list) clauses = [] atoms_fixed = [] t_args = None fixed_only = True for atom in atoms: if atom.probability and atom.probability.functor == 't': assert (atom in self.names) # assert (t_args is None or atom.probability.args == t_args) # t_args = atom.probability.args index = self.output_names.index(atom) weights = self.get_weights(index) for w_args, w_val in weights: translate = tuple( zip(atom.probability.args[1:], w_args.args)) transforms[translate].append( atom.with_probability(Constant(w_val))) self.output_names[index] = None fixed_only = False else: atoms_fixed.append(atom) if not fixed_only: clauses = [] for tr, atoms in transforms.items(): tr = DefaultDict({k: v for k, v in tr}) atoms_out = [at.apply(tr) for at in atoms] + atoms_fixed if len(atoms_out) == 1: if body is None: clauses.append(atoms_out[0]) else: clauses.append(Clause(atoms_out[0], body.apply(tr))) else: if body is None: clauses.append(AnnotatedDisjunction(atoms_out, None)) else: clauses.append( AnnotatedDisjunction(atoms_out, body.apply(tr))) return clauses else: atoms_out = atoms_fixed if len(atoms_out) == 1: if body is None: return [atoms_out[0]] else: return [Clause(atoms_out[0], body)] else: return [AnnotatedDisjunction(atoms_out, body)]
def query(self, player, query, step=0): if (type(step) != int) or (step < 0): raise Exception("Expected step to be None or integer >= cur_step") if player not in self.player_names: raise Exception("{} is an undefined role".format(player)) if player == 'random': raise Exception("Random player does not track knowledge state") return sorted([(prob,pred.args[1]) for (pred, prob) in self._gdl_rep.query(Constant(self._player_map[player]), query, step).items()], \ key=lambda a: a[0], reverse=True)
def call_prolog_insert_positive(user_id, date): p = "" # main_sanita.pl è in utf-16 with codecs.open("prolog/main_sanita.pl", "r", "utf-16") as f: for line in f: p += line p = PrologString(p) # Creazione di un programma Problog dbp = engine.prepare( p ) # Preparazione del programma in un formato comodo per l'engine Problog # Data del nodo rosso più vecchio con cui ha avuto un contatto oldest_match = User.query.get(user_id).oldest_risk_date if oldest_match is None: oldest_match = 0 query = Term("insertPositive", Constant(user_id), Constant(date), Constant(oldest_match)) res = engine.query(dbp, query) # Esecuzione della query
def test_anonymous_variable(self) : """Anonymous variables are distinct""" program = """ p(_,X,_) :- X = 3. q(1,2,3). q(1,2,4). q(2,3,5). r(Y) :- q(_,Y,_). """ engine = DefaultEngine() db = engine.prepare( PrologString(program) ) self.assertEqual( list(map(list,engine.query(db, Term('p', Constant(1), Constant(3), Constant(2) )))), [[Constant(1),Constant(3),Constant(2)]]) self.assertEqual(list(map(list,engine.query(db, Term('r', None )))), [[2], [3]])
def test_add_assignment(self): engine = self.engines['sysadmin'] fluents = engine.declarations('state_fluent') for i in range(2**len(fluents)): state = Term('__s%d__' % i) value = (-1)**(i % 2) * 10.0 * i node = engine.add_assignment(state, value) fact = engine.get_fact(node) self.assertEqual(fact.functor, 'utility') self.assertEqual(fact.args, (state, Constant(value)))
def evaluate_probfoil_rules(hypothesis): if len(hypothesis) == 0: print("Length of hypothesis is 0 while calling evaluate_probfoil_rules") return [] rule = hypothesis rule_list = [] count = 0 if len(hypothesis.to_clauses(hypothesis.target.functor)) > 1: while rule.previous is not None: rule_list.append(copy(rule)) rule_list[count].previous = None rule = rule.previous count += 1 elif len(hypothesis.to_clauses(rule.target.functor)) == 1: rule_list = [hypothesis] result = [] for i, rule in enumerate(rule_list): result.append( Term( "accuracy_rule", Constant(rule.target.functor), Constant(i), Constant(accuracy(rule)), ) ) result.append( Term( "precision_rule", Constant(rule.target.functor), Constant(i), Constant(precision(rule)), ) ) result.append( Term( "recall_rule", Constant(rule.target.functor), Constant(i), Constant(recall(rule)), ) ) return result
def handle_nonground(self, context=None, target=None, **kwdargs): if not hasattr(target, 'skolem'): target.skolem = 0 new_result = [] for r in context: if r is None: new_result.append(Term('skolem', Constant(target.skolem))) target.skolem += 1 else: new_result.append(r) return tuple(new_result)
def test_compare(self) : """Comparison operator""" program = """ morning(Hour) :- Hour >= 6, Hour =< 10. """ engine = DefaultEngine() db = engine.prepare( PrologString(program) ) self.assertEqual( list(map(list,engine.query(db, Term('morning', Constant(8)) ))), [[8]])
def create_fluent(cls, term, timestep): """" Return a new fluent made from `term` with given `timestep`. :param term: any problog term :type term: problog.logic.Term :param timestep: timestep numeric value :type timestep: int :rtype: problog.logic.Term """ args = term.args + (Constant(timestep), ) return term.with_args(*args)