// File: /workspace/github_cpp_makefile_star2_O3/Luthaf[P]zeopp/networkstorage.cc
// Function: find_two_way_connections(ATOM_NETWORK*, std::vector<CONNECTION, std::allocator<CONNECTION>>*)
bool find_two_way_connections(ATOM_NETWORK *cell, vector<CONNECTION> *two_way_connections) {
  bool verbose = false;
  //1) for each VERTEX in the ATOM_NETWORK, look at the edge positions and find which VERTEX it overlaps with periodically - it might be itself!
  vector<CONNECTION> connections;
  int num_v = cell->vertices.size();
  if(verbose) printf("DEBUG: num_v = %d\n", num_v);
  for(int i=0; i<num_v; i++) {
    VERTEX vert = cell->vertices.at(i);
    int num_e = vert.edges.size();
    if(verbose) printf("DEBUG: num_e = %d\n", num_e);
    for(int j=0; j<num_e; j++) {
      XYZ e = vert.edges.at(j);
      int overlap_v_index = -1;
      for(int k=0; k<num_v && overlap_v_index==-1; k++) {
        XYZ v = cell->vertices.at(k).abc;
if(verbose) printf("DEBUG: checking for overlap between edge end position %.3f %.3f %.3f and other vertex position %.3f %.3f %.3f\n", e.x, e.y, e.z, v.x, v.y, v.z);
        if(overlaps_abc(e, v, cell))
          overlap_v_index = k;
      }
      if(overlap_v_index==-1) {
        printf("ERROR: could not construct net: no vertex could be found which overlaps periodically with vertex %d edge %d - check cgd file (did you forget the \":H\" in the symmetry group?)\n", i, j);
        exit(EXIT_FAILURE);
      } else {
        XYZ v = cell->vertices.at(overlap_v_index).abc;
        XYZ shift = e-v;
        int a_shift = (int)(round(shift.x));
        int b_shift = (int)(round(shift.y));
        int c_shift = (int)(round(shift.z));
        if(verbose) printf("DEBUG: vertex %d edge %d at %.3f %.3f %.3f overlaps with vertex %d at %.3f %.3f %.3f with periodicity (%d %d %d)\n", i, j, e.x, e.y, e.z, overlap_v_index, cell->vertices.at(overlap_v_index).abc.x, cell->vertices.at(overlap_v_index).abc.y, cell->vertices.at(overlap_v_index).abc.z, a_shift, b_shift, c_shift);
        CONNECTION c(i, overlap_v_index, j, a_shift, b_shift, c_shift);
        connections.push_back(c);
      }
    }
  }
  int num_connections = connections.size();
  if(verbose) printf("DEBUG: there are %d one-way connections\n", num_connections);
  if(num_connections%2!=0) {
    printf("ERROR: there are an odd number (%d) of one-way connections between vertices - this should not be the case because connections are expressed redundantly\n", num_connections);
    exit(EXIT_FAILURE);
  }
  //2) connections only go one way right now - we cannot yet position molecules because we need to know which edge is used in each VERTEX!
  vector<bool> considered;
  for(int i=0; i<num_connections; i++) considered.push_back(false);
  for(int i=0; i<num_connections; i++) {
    if(!considered.at(i)) { //we are looking at one-way connections - if we have not yet found a match between this connection and another, try and find one
      bool matched = false;
      CONNECTION ci = connections.at(i);
      for(int j=0; j<num_connections; j++) { //we continue searching for matches even after finding one - because we want to handle the error case where edges are declared ambiguously (would be caused by invalid cgd net)
        if(!considered.at(j)) {
          CONNECTION cj = connections.at(j);
          if(matches(ci,cj)) {
            if(matched) {
              printf("ERROR: determined that vertex %d edge %d overlaps with more than one vertex!\n", ci.v1, ci.e1);
              exit(EXIT_FAILURE);
            }
            CONNECTION cij = ci;
            cij.e2 = cj.e1;
            if(verbose) printf("DEBUG: vertex %d edge %d overlaps with vertex %d edge %d with periodicity (%d %d %d)\n", cij.v1, cij.e1, cij.v2, cij.e2, cij.a, cij.b, cij.c);
            two_way_connections->push_back(cij);
            considered.at(i) = true;
            considered.at(j) = true;
            matched = true;
          }
        }
      }
      if(!matched) {
        printf("ERROR: could not find corresponding connection for vertex %d edge %d overlapping with vertex %d\n", ci.v1, ci.e1, ci.v2);
        exit(EXIT_FAILURE);
      }
    }
  }
  int num_two_way_connections = two_way_connections->size();
  if(verbose) printf("DEBUG: there are %d two-way connections\n", num_two_way_connections);
  //3) now we know all the two-way connections, we can recursively traverse until we establish whether the net is disconnected - we need to know this in order to avoid trying the connection-based assembly method later, only to find that it fails
  vector<bool> visited_vertex;
  for(int i=0; i<num_v; i++) visited_vertex.push_back(false);
  recursive_visit_vertices(0, two_way_connections, &visited_vertex);
  bool is_disconnected = false;
  for(int i=0; i<num_v && !is_disconnected; i++) {
    if(!visited_vertex.at(i)) is_disconnected = true;
  }
  return is_disconnected;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1e8, %rsp            # imm = 0x1E8
movq %rsi, %r15
xorpd %xmm0, %xmm0
movapd %xmm0, 0x80(%rsp)
movq $0x0, 0x90(%rsp)
movq 0x3c8(%rdi), %r12
subq 0x3c0(%rdi), %r12
sarq $0x4, %r12
movabsq $0x6db6db6db6db6db7, %rax # imm = 0x6DB6DB6DB6DB6DB7
imulq %rax, %r12
testl %r12d, %r12d
jle 0x5bf4e
movq %rdi, %r14
movq %r15, 0xa0(%rsp)
movl %r12d, %r15d
andl $0x7fffffff, %r15d      # imm = 0x7FFFFFFF
xorl %esi, %esi
movq %r12, 0x128(%rsp)
movq 0x3c0(%r14), %rbx
movq 0x3c8(%r14), %rdx
subq %rbx, %rdx
sarq $0x4, %rdx
movabsq $0x6db6db6db6db6db7, %rax # imm = 0x6DB6DB6DB6DB6DB7
imulq %rax, %rdx
cmpq %rsi, %rdx
jbe 0x5c0cf
movq %rsi, 0x48(%rsp)
imulq $0x70, %rsi, %r12
leaq (%rbx,%r12), %rsi
addq $0x20, %rsi
movupd -0x20(%rsi), %xmm0
movups -0x14(%rsi), %xmm1
movups %xmm1, 0xbc(%rsp)
movapd %xmm0, 0xb0(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x679ba
addq %r12, %rbx
leaq 0x38(%rbx), %rsi
leaq 0xe8(%rsp), %rdi
callq 0x679ba
leaq 0x110(%rsp), %rax
movq %rax, 0x100(%rsp)
movq 0x50(%rbx), %rsi
movq 0x58(%rbx), %rdx
addq %rsi, %rdx
leaq 0x100(%rsp), %rdi
callq 0xf3ce
movq 0xd8(%rsp), %rcx
subq 0xd0(%rsp), %rcx
sarq $0x3, %rcx
movabsq $-0x5555555555555555, %rax # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rcx
movq %rcx, 0x40(%rsp)
testl %ecx, %ecx
jle 0x5bbb6
movq 0x40(%rsp), %rax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq %rax, 0x40(%rsp)
xorl %r12d, %r12d
movq 0xd0(%rsp), %rax
movq 0xd8(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rcx, %rdx
cmpq %r12, %rdx
jbe 0x5c07c
leaq (%r12,%r12,2), %rcx
movq 0x10(%rax,%rcx,8), %rdx
movq %rdx, 0x140(%rsp)
movupd (%rax,%rcx,8), %xmm0
movapd %xmm0, 0x130(%rsp)
movq $-0x1, %r13
xorl %ebp, %ebp
leaq 0x1(%r13), %rbx
movq 0x3c0(%r14), %rax
movq 0x3c8(%r14), %rdx
subq %rax, %rdx
sarq $0x4, %rdx
movabsq $0x6db6db6db6db6db7, %rcx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rcx, %rdx
cmpq %rbx, %rdx
jbe 0x5c06b
movsd 0x10(%rax,%rbp), %xmm0
movups (%rax,%rbp), %xmm1
movaps %xmm1, 0x1b0(%rsp)
movsd %xmm0, 0x1c0(%rsp)
movq 0x1c0(%rsp), %rax
movq %rax, 0x28(%rsp)
movaps 0x1b0(%rsp), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x140(%rsp), %rax
movq %rax, 0x10(%rsp)
movapd 0x130(%rsp), %xmm0
movupd %xmm0, (%rsp)
movq %r14, %rdi
callq 0x59d87
addq $0x2, %r13
cmpq %r15, %r13
setae %cl
orb %al, %cl
addq $0x70, %rbp
movq %rbx, %r13
testb %cl, %cl
je 0x5b9f4
testb %al, %al
je 0x5c09e
movq 0x3c0(%r14), %rax
movq 0x3c8(%r14), %rdx
subq %rax, %rdx
sarq $0x4, %rdx
movabsq $0x6db6db6db6db6db7, %rcx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rcx, %rdx
cmpq %rbx, %rdx
jbe 0x5c08d
movq -0x60(%rax,%rbp), %rcx
movq %rcx, 0x180(%rsp)
movupd -0x70(%rax,%rbp), %xmm0
movapd %xmm0, 0x170(%rsp)
leaq 0x1d0(%rsp), %rdi
leaq 0x130(%rsp), %rsi
leaq 0x170(%rsp), %rdx
callq 0x8461e
movsd 0x1e0(%rsp), %xmm0
callq 0x41d0
cvttsd2si %xmm0, %r13d
movsd 0x1d0(%rsp), %xmm0
movsd %xmm0, 0x78(%rsp)
movsd 0x1d8(%rsp), %xmm0
callq 0x41d0
cvttsd2si %xmm0, %ebp
movsd 0x78(%rsp), %xmm0
callq 0x41d0
cvttsd2si %xmm0, %r8d
movl %r13d, (%rsp)
leaq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
movl %ebx, %edx
movl %r12d, %ecx
movl %ebp, %r9d
callq 0x9d6d4
movq 0x88(%rsp), %rsi
cmpq 0x90(%rsp), %rsi
je 0x5bb96
movupd 0x50(%rsp), %xmm0
movups 0x5c(%rsp), %xmm1
movups %xmm1, 0xc(%rsi)
movupd %xmm0, (%rsi)
addq $0x1c, %rsi
movq %rsi, 0x88(%rsp)
jmp 0x5bba8
leaq 0x80(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0x69132
incq %r12
cmpq 0x40(%rsp), %r12
jne 0x5b99e
movq 0x100(%rsp), %rdi
leaq 0x110(%rsp), %rax
cmpq %rax, %rdi
je 0x5bbdb
movq 0x110(%rsp), %rsi
incq %rsi
callq 0x4470
movq 0xe8(%rsp), %rdi
testq %rdi, %rdi
movq 0x128(%rsp), %r12
je 0x5bc00
movq 0xf8(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xd0(%rsp), %rdi
testq %rdi, %rdi
je 0x5bc1d
movq 0xe0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x48(%rsp), %rsi
incq %rsi
cmpq %r15, %rsi
jne 0x5b8bd
movq 0x88(%rsp), %rbp
subq 0x80(%rsp), %rbp
sarq $0x2, %rbp
movabsq $0x6db6db6db6db6db7, %rax # imm = 0x6DB6DB6DB6DB6DB7
imulq %rax, %rbp
testb $0x1, %bpl
jne 0x5c11b
xorl %eax, %eax
movq %rax, 0xb0(%rsp)
movl %eax, 0xb8(%rsp)
movq %rax, 0xc0(%rsp)
movl %eax, 0xc8(%rsp)
movq %rax, 0xd0(%rsp)
testl %ebp, %ebp
movq 0xa0(%rsp), %r15
jle 0x5bf18
leaq 0xb0(%rsp), %r14
movl %ebp, %ebx
movq %r14, %rdi
xorl %esi, %esi
callq 0xea58
decl %ebx
jne 0x5bc9c
testl %ebp, %ebp
jle 0x5bf18
andl $0x7fffffff, %ebp       # imm = 0x7FFFFFFF
xorl %r14d, %r14d
leaq 0xb0(%rsp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0xee36
testq %rdx, (%rax)
jne 0x5bf0c
movq 0x80(%rsp), %rax
movq 0x88(%rsp), %rdx
subq %rax, %rdx
sarq $0x2, %rdx
movabsq $0x6db6db6db6db6db7, %rcx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rcx, %rdx
cmpq %r14, %rdx
jbe 0x5c0ee
leaq (%r14,%r14,8), %rcx
leaq (%rcx,%rcx,2), %rcx
addq %r14, %rcx
movl (%rax,%rcx), %edx
movl %edx, 0x78(%rsp)
movl 0x4(%rax,%rcx), %edx
movl %edx, 0x48(%rsp)
movl 0x8(%rax,%rcx), %edx
movl %edx, 0x40(%rsp)
movupd 0xc(%rax,%rcx), %xmm0
movapd %xmm0, 0x130(%rsp)
movl $0xc, %r12d
xorl %r13d, %r13d
movq $0x0, 0xa8(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0xee36
testq %rdx, (%rax)
jne 0x5bede
movq 0x80(%rsp), %rax
movq 0x88(%rsp), %rdx
subq %rax, %rdx
sarq $0x2, %rdx
movabsq $0x6db6db6db6db6db7, %rcx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rcx, %rdx
cmpq %r13, %rdx
jbe 0x5c0be
movq %rbx, %r15
movq -0xc(%rax,%r12), %rcx
movl -0x4(%rax,%r12), %ebx
movups (%rax,%r12), %xmm0
movaps %xmm0, 0x170(%rsp)
movl 0x78(%rsp), %eax
movl %eax, 0x150(%rsp)
movl 0x48(%rsp), %eax
movl %eax, 0x154(%rsp)
movl 0x40(%rsp), %eax
movl %eax, 0x158(%rsp)
movaps 0x130(%rsp), %xmm0
leaq 0x15c(%rsp), %rax
movups %xmm0, (%rax)
movq %rcx, 0x190(%rsp)
movl %ebx, 0x198(%rsp)
movaps 0x170(%rsp), %xmm0
leaq 0x19c(%rsp), %rax
movups %xmm0, (%rax)
movups 0x190(%rsp), %xmm0
movups 0x19c(%rsp), %xmm1
movups %xmm1, 0x2c(%rsp)
movups %xmm0, 0x20(%rsp)
movupd 0x150(%rsp), %xmm0
movups 0x15c(%rsp), %xmm1
movups %xmm1, 0xc(%rsp)
movupd %xmm0, (%rsp)
callq 0x9d9ee
testb %al, %al
je 0x5bea6
testb $0x1, 0xa8(%rsp)
jne 0x5c0dd
movl 0x78(%rsp), %eax
movl %eax, 0x50(%rsp)
movl 0x48(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x40(%rsp), %eax
movl %eax, 0x58(%rsp)
movapd 0x130(%rsp), %xmm0
leaq 0x5c(%rsp), %rax
movupd %xmm0, (%rax)
movl %ebx, 0x5c(%rsp)
movq 0xa0(%rsp), %rdi
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x5beab
movupd 0x50(%rsp), %xmm0
movups 0x5c(%rsp), %xmm1
movups %xmm1, 0xc(%rsi)
movupd %xmm0, (%rsi)
addq $0x1c, 0x8(%rdi)
movq %r15, %rbx
jmp 0x5beb8
movq %r15, %rbx
jmp 0x5bede
leaq 0x50(%rsp), %rdx
callq 0x69132
movq %r15, %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0xee36
orq %rdx, (%rax)
movq %rbx, %rdi
movq %r13, %rsi
callq 0xee36
orq %rdx, (%rax)
movb $0x1, %al
movq %rax, 0xa8(%rsp)
incq %r13
addq $0x1c, %r12
cmpq %r13, %rbp
jne 0x5bd4b
testb $0x1, 0xa8(%rsp)
movq 0x128(%rsp), %r12
je 0x5c0ff
movq 0xa0(%rsp), %r15
incq %r14
cmpq %rbp, %r14
jne 0x5bcc3
xorl %eax, %eax
movq %rax, 0x50(%rsp)
movl %eax, 0x58(%rsp)
movq %rax, 0x60(%rsp)
movl %eax, 0x68(%rsp)
movq %rax, 0x70(%rsp)
testl %r12d, %r12d
jle 0x5bf8d
leaq 0x50(%rsp), %rbx
movl %r12d, %ebp
movq %rbx, %rdi
xorl %esi, %esi
callq 0xea58
decl %ebp
jne 0x5bf3e
jmp 0x5bf8d
xorl %eax, %eax
movq %rax, 0xb0(%rsp)
movl %eax, 0xb8(%rsp)
movq %rax, 0xc0(%rsp)
movl %eax, 0xc8(%rsp)
movq %rax, 0xd0(%rsp)
movq %rax, 0x50(%rsp)
movl %eax, 0x58(%rsp)
movq %rax, 0x60(%rsp)
movl %eax, 0x68(%rsp)
movq %rax, 0x70(%rsp)
leaq 0x50(%rsp), %rdx
xorl %edi, %edi
movq %r15, %rsi
callq 0x9e75e
testl %r12d, %r12d
jle 0x5bfd0
andl $0x7fffffff, %r12d      # imm = 0x7FFFFFFF
xorl %r14d, %r14d
leaq 0x50(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0xee36
andq (%rax), %rdx
sete %bl
incq %r14
cmpq %r12, %r14
jae 0x5bfd2
testq %rdx, %rdx
jne 0x5bfb0
jmp 0x5bfd2
xorl %ebx, %ebx
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x5bffd
movq 0x70(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movl %eax, 0x58(%rsp)
movq %rax, 0x60(%rsp)
movl %eax, 0x68(%rsp)
movq %rax, 0x70(%rsp)
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x5c03a
movq 0xd0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movl %eax, 0xb8(%rsp)
movq %rax, 0xc0(%rsp)
movl %eax, 0xc8(%rsp)
movq %rax, 0xd0(%rsp)
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x5c057
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movl %ebx, %eax
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xf1683(%rip), %rdi     # 0x14d6f5
movq %rbx, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xf1672(%rip), %rdi     # 0x14d6f5
movq %r12, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xf1661(%rip), %rdi     # 0x14d6f5
movq %rbx, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xf7235(%rip), %rdi     # 0x1532da
movq 0x48(%rsp), %rsi
movl %r12d, %edx
xorl %eax, %eax
callq 0x4060
movl $0x1, %edi
callq 0x72bc
leaq 0xf1630(%rip), %rdi     # 0x14d6f5
movq %r13, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xf161f(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
leaq 0xf733e(%rip), %rdi     # 0x153422
movl 0x78(%rsp), %esi
movl 0x40(%rsp), %edx
jmp 0x5c0ad
leaq 0xf1600(%rip), %rdi     # 0x14d6f5
movq %r14, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xf736a(%rip), %rdi     # 0x153470
movl 0x78(%rsp), %esi
movl 0x40(%rsp), %edx
movl 0x48(%rsp), %ecx
xorl %eax, %eax
callq 0x4060
jmp 0x5c0b4
leaq 0xf7267(%rip), %rdi     # 0x153389
movl %ebp, %esi
xorl %eax, %eax
callq 0x4060
jmp 0x5c0b4
jmp 0x5c157
jmp 0x5c18b
jmp 0x5c18b
jmp 0x5c18b
jmp 0x5c157
jmp 0x5c18b
jmp 0x5c18b
jmp 0x5c18b
movq %rax, %rbx
jmp 0x5c220
movq %rax, %rbx
jmp 0x5c203
jmp 0x5c14f
movq %rax, %rbx
jmp 0x5c23d
movq %rax, %rbx
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x5c18e
movq 0x70(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movl %eax, 0x58(%rsp)
movq %rax, 0x60(%rsp)
movl %eax, 0x68(%rsp)
movq %rax, 0x70(%rsp)
jmp 0x5c18e
jmp 0x5c18b
jmp 0x5c18b
movq %rax, %rbx
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x5c23d
movq 0xd0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movl %eax, 0xb8(%rsp)
movq %rax, 0xc0(%rsp)
movl %eax, 0xc8(%rsp)
movq %rax, 0xd0(%rsp)
jmp 0x5c23d
jmp 0x5c1db
jmp 0x5c1db
jmp 0x5c1db
jmp 0x5c1db
jmp 0x5c1db
movq %rax, %rbx
movq 0x100(%rsp), %rdi
leaq 0x110(%rsp), %rax
cmpq %rax, %rdi
je 0x5c203
movq 0x110(%rsp), %rsi
incq %rsi
callq 0x4470
movq 0xe8(%rsp), %rdi
testq %rdi, %rdi
je 0x5c220
movq 0xf8(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xd0(%rsp), %rdi
testq %rdi, %rdi
je 0x5c23d
movq 0xe0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x5c25a
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq %rbx, %rdi
callq 0x4780