def index(self, indexer: Indexer): ret = [] two_sums = indexer.index_by_type(TwoSum) equal_conds = indexer.index_by_type(ValueEquivalence) if not equal_conds: return [] for two_sum in two_sums: r = two_sum.relationship for cond in equal_conds: eq_r = cond.relationship if r.entity1 in eq_r.obj_list and r.entity2 in eq_r.obj_list: idx1 = eq_r.obj_list.index(r.entity1) idx2 = eq_r.obj_list.index(r.entity2) if r.attr1 == eq_r.attr_list[ idx1] and r.attr2 == eq_r.attr_list[idx2]: cond1 = indexer.index_value_condition( r.entity1, r.attr1, False) cond2 = indexer.index_value_condition( r.entity2, r.attr2, False) if cond1 is None: cond1 = indexer.index_value_condition( r.entity1, r.attr1) ret.append([[two_sum, cond], cond1]) if cond2 is None: cond2 = indexer.index_value_condition( r.entity2, r.attr2) ret.append([[two_sum, cond], cond2]) return ret
def index(self, indexer: Indexer): ret = [] nls_conds = indexer.index_by_type(NLineSector) for cond in nls_conds: r = cond.relationship # Existence of ratio condition is guaranteed. ratio_cond = indexer.index_value_condition(r, 'ratio') ratio = ratio_cond.attr_value near_point, split_point, far_point = r.three_points line_near = indexer.index_line_by_points(near_point, split_point) line_far = indexer.index_line_by_points(far_point, split_point) line_full = indexer.index_line_by_points(near_point, far_point) near_cond = indexer.index_value_condition(line_near, 'length') far_cond = indexer.index_value_condition(line_far, 'length') full_cond = indexer.index_value_condition(line_full, 'length') if full_cond.attr_value is None: if near_cond.attr_value is not None: ret.append([[near_cond, ratio_cond, 1/ratio], full_cond]) elif far_cond.attr_value is not None: ret.append([[far_cond, ratio_cond, 1/(1-ratio)], full_cond]) if near_cond.attr_value is None: if full_cond.attr_value is not None: ret.append([[full_cond, ratio_cond, ratio], near_cond]) elif far_cond.attr_value is not None: ret.append([[far_cond, ratio_cond, ratio/(1-ratio)], near_cond]) if far_cond.attr_value is None: if full_cond.attr_value is not None: ret.append([[full_cond, ratio_cond, 1-ratio], far_cond]) elif near_cond.attr_value is not None: ret.append([[near_cond, ratio_cond, (1-ratio)/ratio], far_cond]) return ret
def _find_common_vertex_angle(self, cva_cond: RelationshipBased, indexer: Indexer): r = cva_cond.relationship vertex = r.vertex ends = r.ends size = len(ends) for i in range(size): for j in range(i + 1, size): for k in range(j + 1, size): angle_ij = indexer.index_angle_by_points( ends[i], vertex, ends[j]) angle_jk = indexer.index_angle_by_points( ends[j], vertex, ends[k]) angle_ik = indexer.index_angle_by_points( ends[i], vertex, ends[k]) cond_ij = indexer.index_value_condition(angle_ij, 'angle') cond_jk = indexer.index_value_condition(angle_jk, 'angle') cond_ik = indexer.index_value_condition(angle_ik, 'angle') if sum([ cond_ij.attr_value is None, cond_jk.attr_value is None, cond_ik.attr_value is None ]) == 1: return [[cva_cond, cond_ij, cond_jk], (cond_ik)] return None
def _find_common_vertex_angle(self, cva_cond: RelationshipBased, indexer: Indexer): r = cva_cond.relationship vertex = r.vertex ends = r.ends size = len(ends) for i in range(size): for j in range(i + 1, size): for k in range(j + 1, size): angle_ij = indexer.index_angle_by_points( ends[i], vertex, ends[j]) angle_jk = indexer.index_angle_by_points( ends[j], vertex, ends[k]) angle_ik = indexer.index_angle_by_points( ends[i], vertex, ends[k]) cond_ik = indexer.index_value_condition(angle_ik, 'angle') if cond_ik.attr_value is None: continue eq_cond = index_equivalent_value(indexer, angle_ij, 'angle', angle_jk, 'angle') if eq_cond is None: continue cond_ij = indexer.index_value_condition(angle_ij, 'angle') cond_jk = indexer.index_value_condition(angle_jk, 'angle') unkown_cond = [ c for c in [cond_ij, cond_jk] if c.attr_value is None ] if not unkown_cond: continue return [[eq_cond, cond_ik], unkown_cond] return None
def index(self, indexer: Indexer): ret = [] rt_conds = indexer.index_by_type(IsRightTriangle) for cond in rt_conds: r = cond.relationship hypotenuse = r.hypotenuse legs = r.legs a = indexer.index_value_condition(legs[0], 'length') b = indexer.index_value_condition(legs[1], 'length') c = indexer.index_value_condition(hypotenuse, 'length') if attr_value_known_num([a, b, c]) == 2: ret.append([[cond, a, b], c]) return ret
def index(self, indexer: Indexer): ret = [] two_sums = indexer.index_by_type(TwoSum) for two_sum in two_sums: r = two_sum.relationship cond1 = indexer.index_value_condition(r.entity1, r.attr1, False) cond2 = indexer.index_value_condition(r.entity2, r.attr2, False) if cond1 is None and cond2 is not None: cond1 = indexer.index_value_condition(r.entity1, r.attr1) ret.append([[two_sum, cond2], cond1]) elif cond1 is not None and cond2 is None: cond2 = indexer.index_value_condition(r.entity2, r.attr2) ret.append([[two_sum, cond1], cond2]) return ret
def index(self, indexer: Indexer): ret = [] triangles = indexer.index_by_type(Triangle) exist_relations = set() two_sums = indexer.index_by_type(TwoSum) for two_sum in two_sums: exist_relations.add(two_sum.relationship.id) for tri in triangles: known_angles = [] for angle in tri.angles: angle_A_cond = indexer.index_value_condition(angle, 'angle') if angle_A_cond.attr_value is not None: known_angles.append(angle_A_cond) if len(known_angles) >= 2: pairs = itertools.product(known_angles, known_angles) for angle_B_cond, angle_C_cond in pairs: id_ = f'{angle_B_cond.obj.id}.angle_{angle_C_cond.obj.id}.angle' if id_ in exist_relations: continue two_sum_relation = TwoSum( id_, angle_B_cond.obj, 'angle', angle_C_cond.obj, 'angle', angle_B_cond.attr_value + angle_C_cond.attr_value) r = RelationshipBased(two_sum_relation) ret.append([[angle_B_cond, angle_C_cond], r]) return ret
def index(self, indexer: Indexer): ret = [] st_conds = indexer.index_by_type(SimilarTriangle) for cond in st_conds: r = cond.relationship ratio_cond = indexer.index_value_condition(r, 'ratio') if ratio_cond.attr_value is None: continue for side1, side2 in r.cor_sides: s1_cond = indexer.index_value_condition(side1, 'length') s2_cond = indexer.index_value_condition(side2, 'length') if sum( [s1_cond.attr_value is None, s2_cond.attr_value is None]) == 1: ret.append([[cond, s1_cond, ratio_cond], s2_cond]) return ret
def index(self, indexer: Indexer): ret = [] triangles = indexer.index_by_type(Triangle) for th in triangles: side1 = indexer.index_value_condition(th.side1, 'length') if side1.attr_value is None: continue side2 = indexer.index_value_condition(th.side2, 'length') if side2.attr_value is None: continue side3 = indexer.index_value_condition(th.side3, 'length') if side3.attr_value is None: continue ret.append([[side1, side2, side3], AttributeValue(th, **{'circumference': None})]) return ret
def index(self, indexer: Indexer): ret = [] st_conds = indexer.index_by_type(SimilarTriangle) for cond in st_conds: r = cond.relationship for side1, side2 in r.cor_sides: side1_cond = indexer.index_value_condition(side1, 'length') side2_cond = indexer.index_value_condition(side2, 'length') if side1_cond.attr_value is not None \ and side2_cond.attr_value is not None: ratio = indexer.index_value_condition(r, 'ratio') if ratio.attr_value is None: ret.append([[cond, side1_cond, side2_cond], ratio]) break return ret
def index(self, indexer: Indexer): ret = [] triangles = indexer.index_by_type(Triangle) for th in triangles: side1 = indexer.index_value_condition(th.side1, 'length') if side1.attr_value is None: continue side2 = indexer.index_value_condition(th.side2, 'length') if side2.attr_value is None: continue side3 = indexer.index_value_condition(th.side3, 'length') if side3.attr_value is None: continue area = indexer.index_value_condition(th, 'area') if area.attr_value is None: ret.append([[side1, side2, side3], area]) return ret
def index(self, indexer: Indexer): ret = [] rt_conds = indexer.index_by_type(IsRightTriangle) for cond in rt_conds: r = cond.relationship triangle = r.triangle area_cond = indexer.index_value_condition(triangle, 'area') # If area is already known, skip. if area_cond.attr_value is not None: continue leg1_cond = indexer.index_value_condition(r.legs[0], 'length') if leg1_cond.attr_value is None: continue leg2_cond = indexer.index_value_condition(r.legs[1], 'length') if leg2_cond.attr_value is None: continue ret.append([[cond, leg1_cond, leg2_cond], area_cond]) return ret
def index(self, indexer: Indexer): ret = [] rt_conds = indexer.index_by_type(IsRightTriangle) for cond in rt_conds: r = cond.relationship angle = r.right_angle angle_cond = indexer.index_value_condition(angle, 'angle') if angle_cond.attr_value is None: ret.append([[cond], angle_cond]) return ret
def index(self, indexer: Indexer): ret = [] nas_conds = indexer.index_by_type(NAngleSector) for cond in nas_conds: r = cond.relationship # Existence of ratio condition is guaranteed. ratio_cond = indexer.index_value_condition(r, 'ratio') ratio = ratio_cond.attr_value p_near, p_split, p_far = r.three_ends vertex = r.vertex angle_near = indexer.index_angle_by_points(p_near, vertex, p_split) angle_far = indexer.index_angle_by_points(p_far, vertex, p_split) angle_full = indexer.index_angle_by_points(p_near, vertex, p_far) near_cond = indexer.index_value_condition(angle_near, 'angle') far_cond = indexer.index_value_condition(angle_far, 'angle') full_cond = indexer.index_value_condition(angle_full, 'angle') if full_cond.attr_value is None: if near_cond.attr_value is not None: ret.append([[near_cond, ratio_cond, 1 / ratio], full_cond]) elif far_cond.attr_value is not None: ret.append([[far_cond, ratio_cond, 1 / (1 - ratio)], full_cond]) if near_cond.attr_value is None: if full_cond.attr_value is not None: ret.append([[full_cond, ratio_cond, ratio], near_cond]) elif far_cond.attr_value is not None: ret.append([[far_cond, ratio_cond, ratio / (1 - ratio)], near_cond]) if far_cond.attr_value is None: if full_cond.attr_value is not None: ret.append([[full_cond, ratio_cond, 1 - ratio], far_cond]) elif near_cond.attr_value is not None: ret.append([[near_cond, ratio_cond, (1 - ratio) / ratio], far_cond]) return ret
def _find_lines_by_collineation(self, col_cond: RelationshipBased, indexer: Indexer): col = col_cond.relationship ps = col.points size = len(ps) # Find line sum permutation. for i in range(size): for j in range(i + 1, size): for k in range(j + 1, size): line_ij = indexer.index_line_by_points(ps[i], ps[j]) line_jk = indexer.index_line_by_points(ps[j], ps[k]) line_ik = indexer.index_line_by_points(ps[i], ps[k]) cond_ij = indexer.index_value_condition(line_ij, 'length') cond_jk = indexer.index_value_condition(line_jk, 'length') cond_ik = indexer.index_value_condition(line_ik, 'length') if sum([ cond_ij.attr_value == None, cond_jk.attr_value == None, cond_ik.attr_value == None ]) == 1: return [[col_cond, cond_ij, cond_jk], (cond_ik)] return None
def index(self, indexer: Indexer): ret = [] e_conds = indexer.index_by_type(IsEquilateralTriangle) for cond in e_conds: r = cond.relationship tg = [] for angle in r.triangle.angles: angle_cond = indexer.index_value_condition(angle, 'angle') if angle_cond.attr_value is None: tg.append(angle_cond) for t in tg: ret.append([[cond], t]) return ret
def index(self, indexer: Indexer): ret = [] conds = indexer.index_by_type(OppositeVerticalAngle) for cond in conds: r = cond.relationship angle1_cond = indexer.index_value_condition(r.angle1, 'angle') angle2_cond = indexer.index_value_condition(r.angle2, 'angle') if angle1_cond.attr_value is not None and \ angle2_cond.attr_value is None: ret.append([[cond, angle1_cond], angle2_cond]) elif angle1_cond.attr_value is None and \ angle2_cond.attr_value is not None: ret.append([[cond, angle2_cond], angle1_cond]) return ret
def index(self, indexer: Indexer): ret = [] st_conds = indexer.index_by_type(SimilarTriangle) for cond in st_conds: r = cond.relationship for angle1, angle2 in r.cor_angle: a1_cond = indexer.index_value_condition(angle1, 'angle') a2_cond = indexer.index_value_condition(angle2, 'angle') if a1_cond.attr_value is None \ and a2_cond.attr_value is not None: ret.append([[cond, a2_cond], a1_cond]) elif a1_cond.attr_value is not None \ and a2_cond.attr_value is None: ret.append([[cond, a1_cond], a2_cond]) return ret
def index(self, indexer: Indexer): ret = [] i_conds = indexer.index_by_type(IsIsoscelesTriangle) for cond in i_conds: r = cond.relationship h = r.hypotenuse h0_cond = indexer.index_value_condition(h[0], 'length') h1_cond = indexer.index_value_condition(h[1], 'length') if h0_cond.attr_value is None \ and h1_cond.attr_value is not None: ret.append([[cond, h1_cond], h0_cond]) elif h0_cond.attr_value is not None \ and h1_cond.attr_value is None: ret.append([[cond, h0_cond], h1_cond]) return ret
def index(self, indexer: Indexer): ret = [] i_conds = indexer.index_by_type(IsIsoscelesTriangle) for cond in i_conds: r = cond.relationship base_angle = r.base_angle a0_cond = indexer.index_value_condition(base_angle[0], 'angle') a1_cond = indexer.index_value_condition(base_angle[1], 'angle') if a0_cond.attr_value is None \ and a1_cond.attr_value is not None: ret.append([[cond, a1_cond], a0_cond]) elif a0_cond.attr_value is not None \ and a1_cond.attr_value is None: ret.append([[cond, a0_cond], a1_cond]) return ret
def index(self, indexer: Indexer): ret = [] r_conds = indexer.index_by_type(IsRightTriangle) triangles = indexer.index_by_type(Triangle) right_triangles = [cond.relationship.triangle for cond in r_conds] for th in triangles: if th in right_triangles: continue for angle in [th.angle1, th.angle2, th.angle3]: a_cond = indexer.index_value_condition(angle, 'angle') if a_cond.attr_value is not None and a_cond.attr_value == 90: rt = IsRightTriangle(th.id, th, angle) rt_cond = RelationshipBased(rt) ret.append([[a_cond], rt_cond]) break return ret
def index(self, indexer: Indexer): ret = [] triangles = indexer.index_by_type(Triangle) exist_relations = {} two_sums = indexer.index_by_type(TwoSum) for two_sum in two_sums: exist_relations[two_sum.relationship.id] = two_sum for tri in triangles: for angle in tri.angles: angle_A_cond = indexer.index_value_condition(angle, 'angle') if angle_A_cond.attr_value is None: angle_B, angle_C = [a for a in tri.angles if a != angle] id_ = f'{angle_B.id}.angle_{angle_C.id}.angle' if id_ in exist_relations: two_angle_sum = exist_relations[id_] ret.append([[two_angle_sum], angle_A_cond]) return ret
def index(self, indexer: Indexer): ret = [] e_conds = indexer.index_by_type(IsEquilateralTriangle) for cond in e_conds: r = cond.relationship pre = [] tg = [] for side in r.triangle.sides: side_cond = indexer.index_value_condition(side, 'length') if side_cond.attr_value is None: tg.append(side_cond) else: pre.append(side_cond) if pre: pre = [cond] + pre for t in tg: ret.append([pre, t]) return ret
def index(self, indexer: Indexer): ret = [] conds = indexer.index_by_type(SupplementaryAngle) exist_relations = set() two_sums = indexer.index_by_type(TwoSum) for two_sum in two_sums: exist_relations.add(two_sum.relationship.id) for cond in conds: r = cond.relationship angle1_cond = indexer.index_value_condition(r.angle1, 'angle') angle2_cond = indexer.index_value_condition(r.angle2, 'angle') id_ = f'{angle1_cond.obj.id}.angle_{angle2_cond.obj.id}.angle' if id_ in exist_relations: continue two_sum_relation = TwoSum(id_, angle1_cond.obj, 'angle', angle2_cond.obj, 'angle', 180) r = RelationshipBased(two_sum_relation) ret.append([[cond], r]) return ret
def index(self, indexer: Indexer): ret = [] conds = indexer.index_by_type(Perpendicular) for cond in conds: r = cond.relationship line1 = r.line1 line2 = r.line2 if r.foot_point is None: r.foot_point = indexer.index_line_intersection(line1, line2) foot_point = r.foot_point for p1 in [line1.end1, line1.end2]: for p2 in [line2.end1, line2.end2]: if p1 == foot_point or p2 == foot_point: continue angle = indexer.index_angle_by_points(p1, foot_point, p2) angle_cond = indexer.index_value_condition(angle, 'angle') if angle_cond.attr_value is None: ret.append([[cond], AttributeValue(angle, **{'angle': None})]) return ret
def index(self, indexer: Indexer): ret = [] triangles = indexer.index_by_type(Triangle) exist_relations = set() two_sums = indexer.index_by_type(TwoSum) for two_sum in two_sums: exist_relations.add(two_sum.relationship.id) for tri in triangles: for angle in tri.angles: angle_A_cond = indexer.index_value_condition(angle, 'angle') if angle_A_cond.attr_value is not None: angle_B, angle_C = [a for a in tri.angles if a != angle] id_ = f'{angle_B.id}.angle_{angle_C.id}.angle' if id_ in exist_relations: continue two_sum_relation = TwoSum(id_, angle_B, 'angle', angle_C, 'angle', 180 - angle_A_cond.attr_value) r = RelationshipBased(two_sum_relation) ret.append([[angle_A_cond], r]) return ret
def index(self, indexer: Indexer): ret = [] i_conds = indexer.index_by_type(IsIsoscelesTriangle) triangles = indexer.index_by_type(Triangle) isosceles_triangles = [cond.relationship.triangle for cond in i_conds] for th in triangles: if th in isosceles_triangles: continue permutaton = [(th.side1, th.side2, th.vertex3), \ (th.side1, th.side3, th.vertex2), \ (th.side2, th.side3, th.vertex1)] for s1, s2, v in permutaton: s1_cond = indexer.index_value_condition(s1, 'length') s2_cond = indexer.index_value_condition(s2, 'length') if s1_cond.attr_value is None or s2_cond.attr_value is None: continue if s1_cond.attr_value == s2_cond.attr_value: it = IsIsoscelesTriangle(th.id, th, v) it_cond = RelationshipBased(it) ret.append([[s1_cond, s2_cond], it_cond]) break return ret
def index(self, indexer: Indexer): ret = [] i_conds = indexer.index_by_type(IsIsoscelesTriangle) triangles = indexer.index_by_type(Triangle) isosceles_triangles = [cond.relationship.triangle for cond in i_conds] for th in triangles: if th in isosceles_triangles: continue permutaton = [(th.angle1, th.angle2, th.vertex3), \ (th.angle1, th.angle3, th.vertex2), \ (th.angle2, th.angle3, th.vertex1)] for a1, a2, v in permutaton: a1_cond = indexer.index_value_condition(a1, 'angle') a2_cond = indexer.index_value_condition(a2, 'angle') if a1_cond.attr_value is None or a2_cond.attr_value is None: continue if a1_cond.attr_value == a2_cond.attr_value: it = IsIsoscelesTriangle(th.id, th, v) it_cond = RelationshipBased(it) ret.append([[a1_cond, a2_cond], it_cond]) break return ret
def index(self, indexer: Indexer): ret = [] e_conds = indexer.index_by_type(IsEquilateralTriangle) triangles = indexer.index_by_type(Triangle) e_triangles = [cond.relationship.triangle for cond in e_conds] def f(th): for i in range(3): a_cond = indexer.index_value_condition(th.angles[i], 'angle') if a_cond.attr_value is None or a_cond.attr_value != 60: yield False else: yield True for th in triangles: if th in e_triangles: continue if all(f(th)): pre = [indexer.index_value_condition(th.angles[i], 'angle') \ for i in range(3)] r = IsEquilateralTriangle(th.id, th) tg = RelationshipBased(r) ret.append([pre, tg]) return ret