def generate_inverse_implication( group: TimeIntervalsGroup, table: InverseRelationshipsTable) -> List[Clause]: """ Generate the clauses using the inverse implication algorithm. :param group: the time intervals group to execute the algorithm on. :param table: the inverse relationships table. :return: the generated clauses. """ inverse_of = inverse_relationships_to_dict(table) # Now build the clauses. for intervals_relationships in group.intervals_relationships: for relationship in intervals_relationships.relationships: # Skip the equal relationship since it always generates a true value. if relationship == Relationship.EQUAL: continue yield [ Literal(intervals_relationships.t1, intervals_relationships.t2, relationship, True), Literal(intervals_relationships.t2, intervals_relationships.t1, inverse_of[relationship]) ] yield [ Literal(intervals_relationships.t2, intervals_relationships.t1, inverse_of[relationship], True), Literal(intervals_relationships.t1, intervals_relationships.t2, relationship) ]
def generate_clause_for_triplet(dicts: Dicts, t1: int, t2: int, t3: int) -> Optional[List[Clause]]: generated_clauses: List[Clause] = [] t1_t2_relationships: List[Relationship] = dicts.intervals_dict[(t1, t2)] t2_t3_relationships: List[Relationship] = dicts.intervals_dict[(t2, t3)] for r_t1_t2 in t1_t2_relationships: for r_t2_t3 in t2_t3_relationships: t1_t3_relationships: List[ Relationship] = dicts.relationships_dict[(r_t1_t2, r_t2_t3)] clause_for_triplet: Clause = [ Literal(t1, t2, r_t1_t2, True), Literal(t2, t3, r_t2_t3, True) ] added_at_least_something = False for r in t1_t3_relationships: # Before adding the relationship to the list we first need to check if it's actually possible for # the first and third time interval to have that relationship. If not, we skip adding this one. if ((t1, t3) in dicts.intervals_dict) and ( r in dicts.intervals_dict[(t1, t3)]): clause_for_triplet.append(Literal(t1, t3, r)) added_at_least_something = True if added_at_least_something: generated_clauses.append(clause_for_triplet) return generated_clauses
def is_literal_identified(self, literal: Literal): """ Is the given simple literal identified yet? :param literal: the literal's data. :return: the identification status. """ return literal.as_tuple() in self.identified_literals
def get_literal_number(self, literal: Literal): """ Get the number of an already-identified simple literal. :param literal: the literal's data. :return: the literal's identifier. """ return self.identified_literals[literal.as_tuple()]
def generate_at_most_one(group: TimeIntervalsGroup) -> List[Clause]: """ Generate the clauses using the at most one algorithm. :param group: the time intervals group to execute the algorithm on. :return: the generated clauses. """ for intervals_relationships in group.intervals_relationships: # With this loop duplicates are eliminated. for i in range(len(intervals_relationships.relationships)): for j in range(i + 1, len(intervals_relationships.relationships)): r1 = intervals_relationships.relationships[i] r2 = intervals_relationships.relationships[j] yield [ Literal(intervals_relationships.t1, intervals_relationships.t2, r1, True), Literal(intervals_relationships.t1, intervals_relationships.t2, r2, True) ]
def register_literal(self, literal: Literal) -> int: """ Add a new association for a given simple literal. :param literal: the literal's data. :return: the new identification number for the literal. """ old_number = self._current_number self.identified_literals[literal.as_tuple()] = self._current_number self.reverse_identified_literals[self._current_number] = literal self._current_number += 1 return old_number
def generate_at_least_one(group: TimeIntervalsGroup) -> List[Clause]: """ Generate the clauses using the at least one algorithm. :param group: the time intervals group to execute the algorithm on. :return: the generated clauses. """ for intervals_relationships in group.intervals_relationships: clause: Clause = [] for relationship in intervals_relationships.relationships: clause.append( Literal(intervals_relationships.t1, intervals_relationships.t2, relationship)) yield clause
def generate_clause_for_triplet(dicts: Dicts, t1: int, t2: int, t3: int) -> Optional[List[Clause]]: generated_clauses: List[Clause] = [] t1_t2_relationships = dicts.intervals_dict[(t1, t2)] t2_t3_relationships = dicts.intervals_dict[(t2, t3)] for r_t1_t2 in t1_t2_relationships: clause: Clause = [Literal(t1, t2, r_t1_t2, True)] for r_t2_t3 in t2_t3_relationships: t1_t3_relationships = dicts.relationships_dict[(r_t1_t2, r_t2_t3)] for r_t1_t3 in t1_t3_relationships: left_right_implication: Clause = [] right_left_implication_1: Clause = [] right_left_implication_2: Clause = [] # Use a proposition that demonstrates the implication from left to right. left_right_implication.append( Literal(t2, t3, r_t2_t3, True)) left_right_implication.append( Literal(t1, t3, r_t1_t3, True)) left_right_implication.append( ExpressionLiteral(Literal(t2, t3, r_t2_t3), Literal(t1, t3, r_t1_t3))) # Use a proposition that demonstrates the implication from right to left. right_left_implication_1.append(Literal(t2, t3, r_t2_t3)) right_left_implication_1.append( ExpressionLiteral(Literal(t2, t3, r_t2_t3), Literal(t1, t3, r_t1_t3), True)) right_left_implication_2.append(Literal(t1, t3, r_t1_t3)) right_left_implication_2.append( ExpressionLiteral(Literal(t2, t3, r_t2_t3), Literal(t1, t3, r_t1_t3), True)) # Add all generated clauses to the master list. generated_clauses.append(left_right_implication) generated_clauses.append(right_left_implication_1) generated_clauses.append(right_left_implication_2) # Add the clause we wanted to generate in the first place using # the previously generated expression literals. for r in t1_t3_relationships: if ((t1, t3) in dicts.intervals_dict) and ( r in dicts.intervals_dict[(t1, t3)]): clause.append( ExpressionLiteral(Literal(t2, t3, r_t2_t3), Literal(t1, t3, r))) generated_clauses.append(clause) return generated_clauses