Beispiel #1
0
    def test_anchored_creation(self):
        o1 = SObject.Create([3])
        o1_anc = SAnchored(o1, [], 3, 3)

        o2 = SObject.Create([40])
        o2_anc = SAnchored(o2, [], 4, 4)

        o3 = SObject.Create([30])
        o3_anc = SAnchored(o3, [], 5, 5)

        # Create expects anchored objects...
        self.assertRaises(FargError, SAnchored.Create, (o1, ))

        # With a single arg, the object is returned unchanged.
        self.assertEqual(o1_anc, SAnchored.Create((o1_anc, )))

        # With multiple args, we expect the positions of these to be adjacent.
        self.assertRaises(NonAdjacentGroupElementsException, SAnchored.Create,
                          (o1_anc, o3_anc))

        # This also implies that elements may not be repeated:
        self.assertRaises(NonAdjacentGroupElementsException, SAnchored.Create,
                          (o1_anc, o1_anc))

        # If ranges are fine, the group is constructed fine:
        o123_anc = SAnchored.Create((o1_anc, o2_anc, o3_anc))
        self.assertEqual((3, 5), o123_anc.Span())
        self.assertEqual((3, 40, 30), o123_anc.Structure())
Beispiel #2
0
  def test_replacement(self):
    new_group = SAnchored.Create((SAnchored(SElement(7), (), 7, 7),
                                  SAnchored(SElement(8), (), 8, 8),
                                  SAnchored(SElement(9), (), 9, 9)))

    ws = Workspace()
    ws.InsertElements(range(0, 10))
    helper_create_and_insert_groups(ws, ((1, 2, 3), (4, 5, 6), (7, 8)))
    existing_group = list(ws.GetGroupsWithSpan(Exactly(7), Exactly(8)))[0]
    # Cannot replace a group which is not the topmost.
    self.assertRaises(CannotReplaceSubgroupException,
                      ws.Replace, existing_group, new_group)

    ws = Workspace()
    ws.InsertElements(range(0, 10))
    helper_create_and_insert_groups(ws, (7, 8))
    existing_group = list(ws.GetGroupsWithSpan(Exactly(7), Exactly(8)))[0]
    ws.Replace(existing_group, new_group)
    self.assertTrue(existing_group not in ws.groups)
    self.assertEqual(1, len(list(ws.GetGroupsWithSpan(Exactly(7), Exactly(9)))))

    # So now (7, 8, 9) is a group. Let's add a group (5, 6) and try and extend it to 5:8
    helper_create_and_insert_groups(ws, (5, 6))
    existing_group = list(ws.GetGroupsWithSpan(Exactly(5), Exactly(6)))[0]
    new_group = SAnchored.Create((SAnchored(SElement(5), (), 5, 5),
                                  SAnchored(SElement(6), (), 6, 6),
                                  SAnchored(SElement(7), (), 7, 7),
                                  SAnchored(SElement(8), (), 8, 8)))
    self.assertRaises(ConflictingGroupException,
                      ws.Replace, existing_group, new_group)
    # The original group still exists
    self.assertTrue(existing_group in ws.groups)
Beispiel #3
0
    def _PlonkIntoPlace(self, group, *, parents=None):
        """Anchors the group into the workspace. Assumes that conflicts have already been checked
           for.
        """
        groups_at_this_location = list(self.GetGroupsWithSpan(Exactly(group.start_pos),
                                                              Exactly(group.end_pos)))
        if groups_at_this_location:
            # Merge current group into the group at this location, as it were. This merging only
            # adds the underlying mapping. However, if we extend groups to make multiple
            # underlying mappings possible, this needs to be updated too.
            group_at_this_location = groups_at_this_location[
                0]  # There can be only 1
            if (group.object.underlying_mapping_set and
                    not group_at_this_location.object.underlying_mapping_set):
                group_at_this_location.object.underlying_mapping_set = set(
                    group.object.underlying_mapping_set)
            # We should also merge all pieces of the group into the
            # corresponding existing pieces.
            for x in group.items:
                self._PlonkIntoPlace(x)  # Ignore output, we don't need it.
            group_at_this_location.object.AddCategoriesFrom(group.object)
            return group_at_this_location

        # Group does not exist, create one.
        pieces = [self._PlonkIntoPlace(x) for x in group.items]
        new_object = SAnchored.Create(pieces,
                                      underlying_mapping_set=set(
                                          group.object.underlying_mapping_set))
        new_object.object.AddCategoriesFrom(group.object)
        self.groups.add(new_object)
        History.AddArtefact(new_object,
                            ObjectType.WS_GROUP, "Initial creation: [%d, %d]" % (new_object.start_pos,
                                                                                 new_object.end_pos),
                            parents=parents)
        return new_object
Beispiel #4
0
def helper_create_group_given_spans_of_items(ws, *spans):
  anchored_items = []
  for span in spans:
    if isinstance(span, int):
      anchored_items.append(ws.elements[span])
    else:
      matching_groups = ws.GetGroupsWithSpan(Exactly(span[0]), Exactly(span[1]))
      anchored_items.append(next(matching_groups))
  return SAnchored.Create(anchored_items)
Beispiel #5
0
  def test_insert_group(self):
    ws = Workspace()
    ws.InsertElements((5, 6))
    gp = SAnchored.Create(ws.elements[:])
    self.assertEqual((0, 1), gp.Span())
    self.assertEqual((5, 6), gp.Structure())

    ws.InsertGroup(gp)
    self.assertEqual(1, len(ws.groups))
Beispiel #6
0
 def InsertElement(self, element):
     """Insert an element beyond the last element."""
     assert isinstance(element, SElement)
     anchored = SAnchored(sobj=element,
                          items=[],
                          start_pos=self.num_elements,
                          end_pos=self.num_elements,
                          is_sequence_element=True)
     self.num_elements += 1
     History.AddArtefact(anchored, ObjectType.WS_GROUP, "Initial creation")
     History.Note("Element Inserted")
     self.elements.append(anchored)
    def test_sanity(self):
        myltm = LTMGraph(filename=self.filename)
        o1 = SObject.Create([1])
        o1b = SObject.Create([1])
        o2 = SObject.Create([2])
        o12 = SObject.Create([1, 2])
        o123 = SObject.Create([1, 2, 3])
        o1_23 = SObject.Create([1, (2, 3)])

        self.assertNotEqual(o1, o1b)
        self.assertEqual(o1.GetLTMStorableContent(),
                         o1b.GetLTMStorableContent())
        self.assertEqual(myltm.GetNode(content=o1), myltm.GetNode(content=o1b))

        for content in (o1, o1b, o2, o12, o123, o1_23):
            myltm.GetNode(content=content)

        self.assertEqual(myltm.GetNode(content=o1),
                         myltm.GetNode(content=SAnchored(o1, None, 5, 5)))

        self.assertEqual(myltm.GetNode(content=SAnchored(o1b, None, 6, 6)),
                         myltm.GetNode(content=SAnchored(o1, None, 5, 5)))

        self.assertNotEqual(
            myltm.GetNode(content=SAnchored(o1b, None, 6, 6)),
            myltm.GetNode(content=SAnchored(o1_23, None, 5, 7)))

        node = myltm.GetNode(content=SAnchored(o1_23, None, 5, 7))
        self.assertEqual(LTMStorableSObject, node.content.__class__)
        self.assertEqual((1, (2, 3)), node.content.structure)

        myltm.DumpToFile()

        myltm2 = LTMGraph(filename=self.filename)
        self.assertEqual(5, len(myltm2.nodes))
Beispiel #8
0
    def test_plonk_into_place(self):
        ws = Workspace()
        ws.InsertElements((7, 8, 7, 8, 9))

        # Plonk an element... returns existing element.
        elt = SAnchored(SElement(8), (), 3, 3)
        self.assertEqual(ws.elements[3], ws._PlonkIntoPlace(elt))

        # Plonk a group, one item of which is an existing element, one novel. The plonked group
        # has the existing element as a subgroup.
        elt0 = SAnchored(SElement(7), (), 0, 0)
        elt1 = SAnchored(SElement(8), (), 1, 1)
        elt2 = SAnchored(SElement(7), (), 2, 2)
        elt3 = SAnchored(SElement(8), (), 3, 3)
        elt4 = SAnchored(SElement(9), (), 4, 4)
        numeric_successor = NumericMapping(name="succ", category=Number())
        numeric_sameness = NumericMapping(name="same", category=Number())

        successor_mapping_based_cat = MappingBasedCategory(
            mapping=numeric_successor)

        next_ascending = StructuralMapping(
            category=MappingBasedCategory(mapping=numeric_successor),
            bindings_mapping=frozenset((('length', numeric_successor),
                                        ('start', numeric_sameness))))
        gp1 = SAnchored.Create(
            (elt0, elt1), underlying_mapping_set={numeric_successor})
        gp2 = SAnchored.Create(
            (elt2, elt3, elt4), underlying_mapping_set={numeric_successor})
        gp3 = SAnchored.Create(
            (gp1, gp2), underlying_mapping_set={next_ascending})

        self.assertTrue(gp1.object.IsKnownAsInstanceOf(
            successor_mapping_based_cat))

        plonked = ws._PlonkIntoPlace(gp3)
        self.assertEqual(((7, 8), (7, 8, 9)), plonked.Structure())
        existing_groups = list(ws.GetGroupsWithSpan(Exactly(0), Exactly(1)))
        self.assertEqual(existing_groups[0], plonked.items[0])
        self.assertTrue(plonked.items[0].object.IsKnownAsInstanceOf(
            successor_mapping_based_cat))
        self.assertTrue(numeric_successor in plonked.items[
                        0].object.underlying_mapping_set)
        self.assertTrue(
            next_ascending in plonked.object.underlying_mapping_set)
Beispiel #9
0
    def test_ltm_storability(self):
        gp = list(self.ws.groups)[0]
        self.assertIsInstance(gp, LTMStorableMixin)
        storable = gp.GetLTMStorableContent()
        self.assertIsInstance(storable, LTMStorableSObject)
        self.assertEqual((5, 6), storable.structure)
        self.assertEqual(gp.GetLTMStorableContent(), storable,
                         "Repeated call gives same value.")

        # A different group with the same structure will also give the same storable.
        self.assertEqual(
            SAnchored.Create((self.ws.elements[0],
                              self.ws.elements[1])).GetLTMStorableContent(),
            storable)
Beispiel #10
0
    def test_group_overlap(self):
        # We can create a second group at same location
        ws = self.ws
        gp = list(ws.groups)[0]
        gp_cp = SAnchored.Create((ws.elements[0], ws.elements[1]))
        self.assertNotIn(gp_cp, ws.groups, "gp_cp not yet part of workspace")
        self.assertNotEqual(gp, gp_cp, "The two groups differ")

        gp2 = SAnchored.Create(ws.elements[:])
        self.assertIn(gp, ws.GetConflictingGroups(gp2))

        gp3 = SAnchored.Create((ws.elements[1], ws.elements[2]))
        # Overlap does not constitute conflict.
        self.assertNotIn(gp, ws.GetConflictingGroups(gp3))

        # Also, groups do not conflict with others at exactly the same location if their structures are
        # identical.
        self.assertNotIn(gp, ws.GetConflictingGroups(gp_cp))

        # However, [[X, Y], Z] SHOULD conflict [X, [Y, Z]]
        gp_XY_Z = ws.InsertGroup(SAnchored.Create((gp, ws.elements[2])))
        gp_X_YZ = SAnchored.Create((ws.elements[0], gp3))
        self.assertIn(gp_XY_Z, ws.GetConflictingGroups(gp_X_YZ))
Beispiel #11
0
    def test_relations(self):
        # I will insert a relation between two groups, test its existence, and then delete one group.
        # The relation should disappear.
        gp = list(self.ws.groups)[0]
        gp2 = self.ws.InsertGroup(SAnchored.Create(self.ws.elements[2:4]))
        rel = Relation(gp, gp2, mapping_set=set())
        rel.InsertSelf()
        self.assertIn(rel, gp.relations, "Ends contain relation")
        self.assertIn(rel, gp2.relations, "Ends contain relation")

        # Now let's delete gp2: gp should have no relations left.
        self.assertEqual(2, len(self.ws.groups))
        self.ws.DeleteGroup(gp2)
        self.assertEqual(1, len(self.ws.groups))
        self.assertNotIn(rel, gp.relations, "End no longer contains relation")
Beispiel #12
0
def helper_create_and_insert_group(ws, specification):
  """Utility for quickly creating groups.

  Each element in the specification is a tuple consisting of integers or of other similarly
  structured tuples. Each generates a group, where the integers correspond to position in the
  workspace.

  A degenerate case is when the specification is an integer, in which case the WS element is
  returned.
  """
  if isinstance(specification, int):
    return ws.elements[specification]
  else:
    anchored_items = list(helper_create_and_insert_group(ws, x) for x in specification)
    new_group = SAnchored.Create(anchored_items)
    ws.InsertGroup(new_group)
    return new_group
Beispiel #13
0
  def HelperCreateAndInsertGroup(workspace, specification, underlying_mapping_set=None):
    """Utility for quickly creating groups.

       Each element in the specification is a tuple consisting of integers or of other
       similarly structured tuples. Each generates a group, where the integers correspond to
       position in the workspace.

       A degenerate case is when the specification is an integer, in which case the WS
       element is returned.
    """
    if isinstance(specification, int):
      return workspace.elements[specification]
    else:
      anchored_items = list(FringeOverlapTest.HelperCreateAndInsertGroup(workspace, x)
                            for x in specification)
      new_group = SAnchored.Create(anchored_items,
                                   underlying_mapping_set=underlying_mapping_set)
      return workspace.InsertGroup(new_group)
Beispiel #14
0
 def Run(cls, controller, left, right, *, me):
     if left not in controller.workspace.groups or right not in controller.workspace.groups:
         # Groups gone, fizzle.
         History.Note("CF_ActOnOverlappingGroups: left group now dead")
         return
     if set(left.items).intersection(set(right.items)):
         # So overlap, and share elements.
         left_underlying_set = left.object.underlying_mapping_set
         right_underlying_set = right.object.underlying_mapping_set
         # TODO(# --- Jan 28, 2012): Even if the following fails, there is reason to try and
         # see how the two may be made to agree.
         if left_underlying_set and left_underlying_set.intersection(
                 right_underlying_set):
             # This calls out for merging!
             new_group_items = sorted(set(left.items).union(set(
                 right.items)),
                                      key=lambda x: x.start_pos)
             logging.debug("New group items: %s",
                           '; '.join(str(x) for x in new_group_items))
             new_group = SAnchored.Create(
                 new_group_items,
                 underlying_mapping_set=left_underlying_set.intersection(
                     right_underlying_set))
             try:
                 controller.workspace.Replace((left, right), new_group)
             except ConflictingGroupException as e:
                 SubspaceDealWithConflictingGroups(
                     controller,
                     workspace_arguments=dict(
                         new_group=new_group,
                         incumbents=e.conflicting_groups),
                     parents=[me, left, right],
                     msg="Conflict when merging overlapping groups").Run()
             except CannotReplaceSubgroupException as e:
                 SubspaceDealWithConflictingGroups(
                     controller,
                     workspace_arguments=dict(new_group=new_group,
                                              incumbents=e.supergroups),
                     parents=[me, left, right],
                     msg=
                     "Cannot replace subgp when merging overlapping groups"
                 ).Run()
 def CreateGroupings(cls, controller, *, me):
     from farg.apps.seqsee.anchored import SAnchored
     from farg.apps.seqsee.sobject import SGroup
     from farg.apps.seqsee.exceptions import ConflictingGroupException
     workspace = controller.workspace
     parent_workspace = controller.parent_controller.workspace
     d = workspace.distance.value + 1
     number_of_groups_possible = int(parent_workspace.num_elements / d)
     size_n_category = SizeNCategory(size=d)
     for k in range(number_of_groups_possible):
         items = [
             parent_workspace.elements[x]
             for x in range(k * d, (k + 1) * d)
         ]
         sobj = SGroup(items=[x.object for x in items])
         group = SAnchored(sobj, items, k * d, (k + 1) * d - 1)
         group.object.DescribeAs(size_n_category)
         try:
             parent_workspace.InsertGroup(group, parent=[me])
         except ConflictingGroupException:
             # TODO(# --- Apr 22, 2012): add an appropriate codelet in top workspace.
             pass
Beispiel #16
0
 def Run(cls, controller, relation, *, me):
     # If there is a group spanning the proposed group, perish the thought.
     left, right = relation.first.start_pos, relation.second.end_pos
     from farg.apps.seqsee.util import GreaterThanEq, LessThanEq
     if tuple(
             controller.workspace.GetGroupsWithSpan(LessThanEq(left),
                                                    GreaterThanEq(right))):
         History.Note("CF_GroupFromRelation: a spanning group exists")
         return
     anchored = SAnchored.Create(
         (relation.first, relation.second),
         underlying_mapping_set=relation.mapping_set)
     try:
         controller.workspace.InsertGroup(anchored, parent=[me])
     except ConflictingGroupException as e:
         SubspaceDealWithConflictingGroups(
             controller,
             workspace_arguments=dict(new_group=anchored,
                                      incumbents=e.conflicting_groups),
             parents=[me, relation],
             msg="Conflict while inserting %s" %
             anchored.BriefLabel()).Run()
Beispiel #17
0
 def test_position(self):
     o2a = SObject.Create([3, 4])
     o2a_anchored = SAnchored(o2a, [], 10, 12)
     self.assertEqual(10, o2a_anchored.start_pos)
Beispiel #18
0
 def setUp(self):
     self.ws = ws = Workspace()
     ws.InsertElements((5, 6, 7, 8))
     ws.InsertGroup(SAnchored.Create((ws.elements[0], ws.elements[1])))
Beispiel #19
0
    def Run(cls, controller, item, *, me):
        if item not in controller.workspace.groups:
            History.Note("CF_ExtendGroup: item not in workspace")
            # item deleted?
            return
        # QUALITY TODO(Feb 14, 2012): Direction to extend choice can be
        # improved.
        extend_right = True
        if (item.start_pos > 0 and Toss(0.5)):
            extend_right = False

        parts = item.items
        underlying_mapping_set = item.object.underlying_mapping_set
        if not underlying_mapping_set:
            History.Note("CF_ExtendGroup: no underlying relations")
            return
        mapping = SelectWeightedByActivation(
            controller.ltm, underlying_mapping_set)
        if extend_right:
            next_part = mapping.Apply(parts[-1].object)
            if not next_part:
                History.Note(
                    "CF_ExtendGroup: could not apply mapping to last part")
                return
            magnitudes = next_part.FlattenedMagnitudes()
            number_of_known_elements = len(
                controller.workspace.elements) - item.end_pos - 1
            if len(magnitudes) > number_of_known_elements:
                # TODO(# --- Feb 14, 2012): This is where we may go beyond known elements.
                # To the extent that the next few elements are known, ensure that they agree with
                # what's known.
                if not controller.workspace.CheckForPresence(item.end_pos + 1,
                                                             magnitudes[:number_of_known_elements]):
                    return
                # The following either returns false soon if the user will not be asked, or asks
                # the user and returns the response. If the response is yes, the elements are also
                # added.
                should_continue = SubspaceGoBeyondKnown(
                    controller,
                    workspace_arguments=dict(basis_of_extension=item,
                                             suggested_terms=magnitudes),
                    parents=[me, item]).Run()
                if not should_continue:
                    return
            else:
                if not controller.workspace.CheckForPresence(item.end_pos + 1, magnitudes):
                    return
            next_part_anchored = SAnchored.CreateAt(
                item.end_pos + 1, next_part)
            new_parts = list(parts[:])
            new_parts.append(next_part_anchored)
        else:
            flipped = mapping.FlippedVersion()
            if not flipped:
                return
            previous_part = flipped.Apply(parts[0].object)
            if not previous_part:
                return
            magnitudes = previous_part.FlattenedMagnitudes()
            if len(magnitudes) > item.start_pos:
                return
            if not controller.workspace.CheckForPresence(item.start_pos - len(magnitudes),
                                                         magnitudes):
                return
            prev_part_anchored = SAnchored.CreateAt(item.start_pos - len(magnitudes),
                                                    previous_part)
            new_parts = [prev_part_anchored]
            new_parts.extend(parts)
        new_group = SAnchored.Create(new_parts,
                                     underlying_mapping_set={mapping})

        from farg.apps.seqsee.exceptions import ConflictingGroupException
        from farg.apps.seqsee.exceptions import CannotReplaceSubgroupException
        from farg.apps.seqsee.subspaces.deal_with_conflicting_groups import SubspaceDealWithConflictingGroups
        try:
            controller.workspace.Replace(item, new_group)
        except ConflictingGroupException as e:
            SubspaceDealWithConflictingGroups(
                controller,
                workspace_arguments=dict(new_group=new_group,
                                         incumbents=e.conflicting_groups),
                parents=[me, item],
                msg="Conflict when replacing item with enlarged group").Run()
        except CannotReplaceSubgroupException as e:
            SubspaceDealWithConflictingGroups(
                controller,
                workspace_arguments=dict(new_group=new_group,
                                         incumbents=e.supergroups),
                parents=[me, item],
                msg="Cannot replace subgp when extending item").Run()