Example #1
0
bool
swap (modification& m1, modification& m2) {
  path rp1= root (m1);
  path rp2= root (m2);
  if (is_nil (rp1))
    switch (m1->k) {
    case MOD_ASSIGN:
      {
	if (m1 == m2) return true;
	if (!is_nil (rp2) || m2->k != MOD_INSERT_NODE) return false;
	modification aux= m2;
	m2= modification (m1->k, path (m2->p->item, m1->p), m1->t);
	m1= aux;
	return true;
      }
    case MOD_INSERT:
      {
	if (is_nil (m2->p)) return false;
	int b= m1->p->item;
	int e= b + insert_length (m1->t);
	if (m2->p->item >= b && m2->p->item < e)
	  if (!is_nil (root (m2)) || m2->p->item != b || m2->k != MOD_INSERT)
	    if (!is_nil (root (m2)) || m2->k != MOD_INSERT_NODE)
	      return false;
	return swap1 (m1, m2, b, e-b);
      }
    case MOD_REMOVE:
      {
	if (is_nil (m2->p)) return false;
	int i= m1->p->item;
	int d= m1->p->next->item;
	return swap1 (m1, m2, i, -d);
      }
    case MOD_SPLIT:
      {
	if (is_nil (m2->p)) return false;
	int i= m1->p->item;
	if (m2->p->item == i || m2->p->item == i+1)
	  if (!is_nil (root (m2)) || m2->p->item != i || m2->k != MOD_INSERT)
	    if (!is_nil (root (m2)) || m2->k != MOD_INSERT_NODE)
	      return false;
	return swap1 (m1, m2, i, 1);
      }
    case MOD_JOIN:
      {
	if (is_nil (m2->p)) return false;
	int i= m1->p->item;
	if (m2->p->item == i)
	  if (!is_nil (root (m2)) || m2->k != MOD_INSERT)
	    return false;
	return swap1 (m1, m2, i, -1);
      }
    case MOD_ASSIGN_NODE:
      {
	if (!is_nil (root (m2))) return swap_basic (m1, m2);
	if (m1 == m2) return true;
	if (!is_nil (rp2) || m2->k != MOD_INSERT_NODE) return false;
	modification aux= m2;
	m2= modification (m1->k, path (m2->p->item, m1->p), m1->t);
	m1= aux;
	return true;
      }
    case MOD_INSERT_NODE:
      {
	if (is_nil (root (m2))) return false;
	if (m2->p->item != m1->p->item) return false;
	modification aux= m1;
	m1= modification (m2->k, m2->p->next, m2->t);
	if (m2->k != MOD_INSERT_NODE || !is_nil (root (m1))) m2= aux;
	else m2= modification (aux->k, path (m1->p->item, aux->p), aux->t);
	return true;
      }
    case MOD_REMOVE_NODE:
      {
	modification aux= m1;
	m1= modification (m2->k, path (m1->p->item, m2->p), m2->t);
	m2= aux;
	return true;
      }
    case MOD_SET_CURSOR:
      {
        if (!is_nil (rp2) ||
            m2->k == MOD_JOIN ||
            m2->k == MOD_SPLIT ||
            m2->k == MOD_ASSIGN_NODE)
          return swap_basic (m1, m2);
        return false;
      }
    }
  else if (is_nil (rp2))
    switch (m2->k) {
    case MOD_ASSIGN:
      return false;
    case MOD_INSERT:
      {
	int b= m2->p->item;
	int e= b + insert_length (m2->t);
	return swap2 (m1, m2, b, e-b);
      }
    case MOD_REMOVE:
      {
	int b= m2->p->item;
	int e= b + m2->p->next->item;
	if (m1->p->item >= b && m1->p->item < e) return false;
	return swap2 (m1, m2, b, b-e);
      }
    case MOD_SPLIT:
      {
	int i= m2->p->item;
	if (m1->p->item == i) return false;
	return swap2 (m1, m2, i, 1);
      }
    case MOD_JOIN:
      {
	int i= m2->p->item;
	if (m1->p->item == i || m1->p->item == i+1) return false;
	return swap2 (m1, m2, i, -1);
      }
    case MOD_ASSIGN_NODE:
      return swap_basic (m1, m2);
    case MOD_INSERT_NODE:
      {
	modification aux= m2;
	m2= modification (m1->k, path (m2->p->item, m1->p), m1->t);
	m1= aux;
	return true;
      }
    case MOD_REMOVE_NODE:
      {
	if (m1->p->item != m2->p->item) return false;
	modification aux= m2;
	m2= modification (m1->k, m1->p->next, m1->t);
	m1= aux;
	return true;
      }
    case MOD_SET_CURSOR:
      {
        if (!is_nil (rp1) ||
            m1->k == MOD_JOIN ||
            m1->k == MOD_SPLIT ||
            m1->k == MOD_ASSIGN_NODE)
          return swap_basic (m1, m2);
        return false;
      }
    }
  else if (rp1->item == rp2->item) {
    path h (rp1->item);
    modification s1= m1 / h;
    modification s2= m2 / h;
    bool r= swap (s1, s2);
    m1= h * s1;
    m2= h * s2;
    return r;
  }
  else return swap_basic (m1, m2);
  FAILED ("unexpected situation");
}
Example #2
0
bool
swap (patch& p1, patch& p2, double a1, double a2) {
  if (is_nil (p1) || is_nil (p2)) return false;
  if (get_type (p1) == PATCH_BRANCH)
    return false;
  if (get_type (p2) == PATCH_BRANCH)
    return false;
  if (get_type (p1) == PATCH_COMPOUND) {
    int n= N(p1);
    array<patch> a (n);
    for (int i=0; i<n; i++) a[i]= p1[i];
    for (int i=n-1; i>=0; i--) {
      if (!swap (a[i], p2, a1, a2)) return false;
      swap_basic (a[i], p2);
    }
    p1= p2;
    p2= patch (a);
    return true;
  }
  if (get_type (p2) == PATCH_COMPOUND) {
    int n= N(p2);
    array<patch> a (n);
    for (int i=0; i<n; i++) a[i]= p2[i];
    for (int i=0; i<n; i++) {
      if (!swap (p1, a[i], a1, a2)) return false;
      swap_basic (p1, a[i]);
    }
    p2= p1;
    p1= patch (a);
    return true;
  }
  if (get_type (p1) == PATCH_AUTHOR) {
    patch s= p1[0];
    bool r= swap (s, p2, get_author (p1), a2);
    p2= patch (get_author (p1), p2);
    p1= s;
    return r;
  }
  if (get_type (p2) == PATCH_AUTHOR) {
    patch s= p2[0];
    bool r= swap (p1, s, a1, get_author (p2));
    p1= patch (get_author (p2), p1);
    p2= s;
    return r;
  }
  if (get_type (p1) == PATCH_BIRTH) {
    if (get_author (p1) == a2) return false;
    return swap_basic (p1, p2);
  }
  if (get_type (p2) == PATCH_BIRTH) {
    if (get_author (p2) == a1) return false;
    return swap_basic (p1, p2);
  }
  if (get_type (p1) == PATCH_MODIFICATION &&
      get_type (p2) == PATCH_MODIFICATION)
    {
      modification m1= get_modification (p1);
      modification m2= get_modification (p2);
      modification i1= get_inverse (p1);
      modification i2= get_inverse (p2);
      bool r= swap (m1, m2);
      bool v= swap (i2, i1);
      p1= patch (m1, i1);
      p2= patch (m2, i2);
      return r && v && possible_inverse (m1, i1) && possible_inverse (m2, i2);
    }
  FAILED ("invalid situation");
  return false;
}
Example #3
0
bool
swap (modification& m1, modification& m2) {
  // Assuming that m1;m2 (the patch m1 followed by m2) is well-defined,
  // determine modifications m1* and m2* such that m2*;m1* is equivalent
  // to m1;m2.  If such modifications exist, then set m1 := m2* and
  // m2 := m1* and return true.  Otherwise, return false
  path rp1= root (m1);
  path rp2= root (m2);
  if (is_nil (rp1))
    switch (m1->k) {
    case MOD_ASSIGN:
      {
	if (m1 == m2) return true;
	if (!is_nil (rp2) || m2->k != MOD_INSERT_NODE) return false;
	modification aux= m2;
	m2= modification (m1->k, path (m2->p->item, m1->p), m1->t);
	m1= aux;
	return true;
      }
    case MOD_INSERT:
      {
	if (is_nil (m2->p)) return false;
	int b= m1->p->item;
	int e= b + insert_length (m1->t);
	if (m2->p->item >= b && m2->p->item < e)
	  if (!is_nil (root (m2)) || m2->p->item != b || m2->k != MOD_INSERT)
	    if (!is_nil (root (m2)) || m2->k != MOD_INSERT_NODE)
	      return false;
	return swap1 (m1, m2, b, e-b);
      }
    case MOD_REMOVE:
      {
	if (is_nil (m2->p)) return false;
	int i= m1->p->item;
	int d= m1->p->next->item;
	return swap1 (m1, m2, i, -d);
      }
    case MOD_SPLIT:
      {
	if (is_nil (m2->p)) return false;
	int i= m1->p->item;
	if (m2->p->item == i || m2->p->item == i+1)
	  if (!is_nil (root (m2)) || m2->p->item != i || m2->k != MOD_INSERT)
	    if (!is_nil (root (m2)) || m2->k != MOD_INSERT_NODE)
	      return false;
	return swap1 (m1, m2, i, 1);
      }
    case MOD_JOIN:
      {
	if (is_nil (m2->p)) return false;
	int i= m1->p->item;
	if (m2->p->item == i)
	  if (!is_nil (root (m2)) || m2->k != MOD_INSERT)
	    return false;
	return swap1 (m1, m2, i, -1);
      }
    case MOD_ASSIGN_NODE:
      {
	if (!is_nil (root (m2))) return swap_basic (m1, m2);
	if (m1 == m2) return true;
	if (!is_nil (rp2) || m2->k != MOD_INSERT_NODE) return false;
	modification aux= m2;
	m2= modification (m1->k, path (m2->p->item, m1->p), m1->t);
	m1= aux;
	return true;
      }
    case MOD_INSERT_NODE:
      {
	if (is_nil (root (m2))) return false;
	if (m2->p->item != m1->p->item) return false;
	modification aux= m1;
	m1= modification (m2->k, m2->p->next, m2->t);
	if (m2->k != MOD_INSERT_NODE || !is_nil (root (m1))) m2= aux;
	else m2= modification (aux->k, path (m1->p->item, aux->p), aux->t);
	return true;
      }
    case MOD_REMOVE_NODE:
      {
	modification aux= m1;
	m1= modification (m2->k, path (m1->p->item, m2->p), m2->t);
	m2= aux;
	return true;
      }
    case MOD_SET_CURSOR:
      {
        if (!is_nil (rp2) ||
            m2->k == MOD_JOIN ||
            m2->k == MOD_SPLIT ||
            m2->k == MOD_ASSIGN_NODE)
          return swap_basic (m1, m2);
        return false;
      }
    }
  else if (is_nil (rp2))
    switch (m2->k) {
    case MOD_ASSIGN:
      return false;
    case MOD_INSERT:
      {
	int b= m2->p->item;
	int e= b + insert_length (m2->t);
	return swap2 (m1, m2, b, e-b);
      }
    case MOD_REMOVE:
      {
	int b= m2->p->item;
	int e= b + m2->p->next->item;
	if (m1->p->item >= b && m1->p->item < e) return false;
	return swap2 (m1, m2, b, b-e);
      }
    case MOD_SPLIT:
      {
	int i= m2->p->item;
	if (m1->p->item == i) return false;
	return swap2 (m1, m2, i, 1);
      }
    case MOD_JOIN:
      {
	int i= m2->p->item;
	if (m1->p->item == i || m1->p->item == i+1) return false;
	return swap2 (m1, m2, i, -1);
      }
    case MOD_ASSIGN_NODE:
      return swap_basic (m1, m2);
    case MOD_INSERT_NODE:
      {
	modification aux= m2;
	m2= modification (m1->k, path (m2->p->item, m1->p), m1->t);
	m1= aux;
	return true;
      }
    case MOD_REMOVE_NODE:
      {
	if (m1->p->item != m2->p->item) return false;
	modification aux= m2;
	m2= modification (m1->k, m1->p->next, m1->t);
	m1= aux;
	return true;
      }
    case MOD_SET_CURSOR:
      {
        if (!is_nil (rp1) ||
            m1->k == MOD_JOIN ||
            m1->k == MOD_SPLIT ||
            m1->k == MOD_ASSIGN_NODE)
          return swap_basic (m1, m2);
        return false;
      }
    }
  else if (rp1->item == rp2->item) {
    path h (rp1->item);
    modification s1= m1 / h;
    modification s2= m2 / h;
    bool r= swap (s1, s2);
    m1= h * s1;
    m2= h * s2;
    return r;
  }
  else return swap_basic (m1, m2);
  FAILED ("unexpected situation");
}