// File: /workspace/github_cpp_makefile_star2_O1/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 $0x1d8, %rsp            # imm = 0x1D8
movq %rsi, 0xa8(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x80(%rsp)
movq $0x0, 0x90(%rsp)
movq 0x3c8(%rdi), %r12
subq 0x3c0(%rdi), %r12
sarq $0x4, %r12
movabsq $0x6db6db6db6db6db7, %rbx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rbx, %r12
testl %r12d, %r12d
movq %r12, 0x120(%rsp)
jle 0x5c191
movq %rdi, %r14
movl %r12d, %r15d
andl $0x7fffffff, %r15d      # imm = 0x7FFFFFFF
xorl %esi, %esi
movq 0x3c0(%r14), %r12
movq 0x3c8(%r14), %rdx
subq %r12, %rdx
sarq $0x4, %rdx
imulq %rbx, %rdx
cmpq %rsi, %rdx
jbe 0x5c612
movq %rsi, 0x40(%rsp)
imulq $0x70, %rsi, %r13
leaq (%r12,%r13), %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 0x682e6
addq %r13, %r12
leaq 0x38(%r12), %rsi
leaq 0xe8(%rsp), %rdi
callq 0x682e6
leaq 0x110(%rsp), %rax
movq %rax, 0x100(%rsp)
movq 0x50(%r12), %rsi
movq 0x58(%r12), %rdx
addq %rsi, %rdx
leaq 0x100(%rsp), %rdi
callq 0xf32a
movq 0xd8(%rsp), %rcx
subq 0xd0(%rsp), %rcx
sarq $0x3, %rcx
movabsq $-0x5555555555555555, %rax # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rcx
movq %rcx, 0x48(%rsp)
testl %ecx, %ecx
jle 0x5c119
movq 0x48(%rsp), %rax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq %rax, 0x48(%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 0x5c5b1
leaq (%r12,%r12,2), %rcx
movq 0x10(%rax,%rcx,8), %rdx
movq %rdx, 0x140(%rsp)
movupd (%rax,%rcx,8), %xmm0
movapd %xmm0, 0x130(%rsp)
movl $0x10, %ebp
xorl %r13d, %r13d
movq 0x3c0(%r14), %rax
movq 0x3c8(%r14), %rdx
subq %rax, %rdx
sarq $0x4, %rdx
imulq %rbx, %rdx
cmpq %r13, %rdx
jbe 0x5c5a0
movsd (%rax,%rbp), %xmm0
movups -0x10(%rax,%rbp), %xmm1
movups %xmm1, 0x1c0(%rsp)
movsd %xmm0, 0x1d0(%rsp)
movq 0x1d0(%rsp), %rax
movq %rax, 0x28(%rsp)
movups 0x1c0(%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 0x5a244
incq %r13
cmpq %r15, %r13
setae %cl
orb %al, %cl
addq $0x70, %rbp
testb %cl, %cl
je 0x5bf52
decl %r13d
testb %al, %al
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmovel %eax, %r13d
je 0x5c5d0
movslq %r13d, %rsi
movq 0x3c0(%r14), %rax
movq 0x3c8(%r14), %rdx
subq %rax, %rdx
sarq $0x4, %rdx
imulq %rbx, %rdx
cmpq %rsi, %rdx
jbe 0x5c5c2
imulq $0x70, %rsi, %rcx
movq 0x10(%rax,%rcx), %rdx
movq %rdx, 0x180(%rsp)
movupd (%rax,%rcx), %xmm0
movapd %xmm0, 0x170(%rsp)
leaq 0x1a8(%rsp), %rdi
leaq 0x130(%rsp), %rsi
leaq 0x170(%rsp), %rdx
callq 0x85da6
movsd 0x1b8(%rsp), %xmm0
callq 0x41d0
cvttsd2si %xmm0, %ebx
movsd 0x1a8(%rsp), %xmm0
movsd %xmm0, 0xa0(%rsp)
movsd 0x1b0(%rsp), %xmm0
callq 0x41d0
cvttsd2si %xmm0, %ebp
movsd 0xa0(%rsp), %xmm0
callq 0x41d0
cvttsd2si %xmm0, %r8d
movl %ebx, (%rsp)
leaq 0x58(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl %r13d, %edx
movl %r12d, %ecx
movl %ebp, %r9d
callq 0x9f2c0
movq 0x88(%rsp), %rsi
cmpq 0x90(%rsp), %rsi
je 0x5c0ef
movupd 0x58(%rsp), %xmm0
movups 0x64(%rsp), %xmm1
movups %xmm1, 0xc(%rsi)
movupd %xmm0, (%rsi)
addq $0x1c, %rsi
movq %rsi, 0x88(%rsp)
jmp 0x5c101
leaq 0x80(%rsp), %rdi
leaq 0x58(%rsp), %rdx
callq 0x69b06
incq %r12
cmpq 0x48(%rsp), %r12
movabsq $0x6db6db6db6db6db7, %rbx # imm = 0x6DB6DB6DB6DB6DB7
jne 0x5befd
movq 0x100(%rsp), %rdi
leaq 0x110(%rsp), %rax
cmpq %rax, %rdi
je 0x5c13e
movq 0x110(%rsp), %rsi
incq %rsi
callq 0x4470
movq 0xe8(%rsp), %rdi
testq %rdi, %rdi
movq 0x120(%rsp), %r12
je 0x5c163
movq 0xf8(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xd0(%rsp), %rdi
testq %rdi, %rdi
je 0x5c180
movq 0xe0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x40(%rsp), %rsi
incq %rsi
cmpq %r15, %rsi
jne 0x5be23
movq 0x88(%rsp), %r13
subq 0x80(%rsp), %r13
sarq $0x2, %r13
imulq %rbx, %r13
testb $0x1, %r13b
jne 0x5c64a
xorl %eax, %eax
movq %rax, 0xb0(%rsp)
movl %eax, 0xb8(%rsp)
movq %rax, 0xc0(%rsp)
movl %eax, 0xc8(%rsp)
movq %rax, 0xd0(%rsp)
testl %r13d, %r13d
jle 0x5c1fa
leaq 0xb0(%rsp), %r14
movl %r13d, %r15d
movq %r14, %rdi
xorl %esi, %esi
callq 0xe9e6
decl %r15d
jne 0x5c1eb
testl %r13d, %r13d
movq 0xa8(%rsp), %r15
jle 0x5c474
andl $0x7fffffff, %r13d      # imm = 0x7FFFFFFF
xorl %r14d, %r14d
leaq 0xb0(%rsp), %rbp
movq %r13, 0xa0(%rsp)
movq %rbp, %rdi
movq %r14, %rsi
callq 0xedb6
testq %rdx, (%rax)
jne 0x5c468
movq %r14, %rsi
movq 0x80(%rsp), %rax
movq 0x88(%rsp), %rdx
subq %rax, %rdx
sarq $0x2, %rdx
imulq %rbx, %rdx
cmpq %r14, %rdx
jbe 0x5c620
movq %rbp, %r14
leaq (%rsi,%rsi,8), %rcx
leaq (%rcx,%rcx,2), %rcx
movq %rsi, 0x128(%rsp)
addq %rsi, %rcx
movl (%rax,%rcx), %edx
movl %edx, 0x48(%rsp)
movl 0x4(%rax,%rcx), %edx
movl %edx, 0x54(%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
xorl %ebp, %ebp
movq %r14, %rdi
movq %r13, %rsi
callq 0xedb6
testq %rdx, (%rax)
jne 0x5c42e
movq 0x80(%rsp), %rax
movq 0x88(%rsp), %rdx
subq %rax, %rdx
sarq $0x2, %rdx
imulq %rbx, %rdx
cmpq %r13, %rdx
jbe 0x5c5f0
movq -0xc(%rax,%r12), %rcx
movl -0x4(%rax,%r12), %r15d
movups (%rax,%r12), %xmm0
movaps %xmm0, 0x170(%rsp)
movl 0x48(%rsp), %eax
movl %eax, 0x150(%rsp)
movl 0x54(%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, 0x188(%rsp)
movl %r15d, 0x190(%rsp)
movaps 0x170(%rsp), %xmm0
leaq 0x194(%rsp), %rax
movups %xmm0, (%rax)
movups 0x188(%rsp), %xmm0
movups 0x194(%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 0x9f5da
testb %al, %al
je 0x5c3f0
testb $0x1, %bpl
jne 0x5c601
movl 0x48(%rsp), %eax
movl %eax, 0x58(%rsp)
movl 0x54(%rsp), %eax
movl %eax, 0x5c(%rsp)
movl 0x40(%rsp), %eax
movl %eax, 0x60(%rsp)
movapd 0x130(%rsp), %xmm0
leaq 0x64(%rsp), %rax
movupd %xmm0, (%rax)
movl %r15d, 0x64(%rsp)
movq 0xa8(%rsp), %r15
movq 0x8(%r15), %rsi
cmpq 0x10(%r15), %rsi
je 0x5c3fa
movupd 0x58(%rsp), %xmm0
movups 0x64(%rsp), %xmm1
movups %xmm1, 0xc(%rsi)
movupd %xmm0, (%rsi)
addq $0x1c, 0x8(%r15)
jmp 0x5c407
movq 0xa8(%rsp), %r15
jmp 0x5c42e
movq %r15, %rdi
leaq 0x58(%rsp), %rdx
callq 0x69b06
movq %r14, %rbp
movq %r14, %rdi
movq 0x128(%rsp), %rsi
callq 0xedb6
orq %rdx, (%rax)
movq %rbp, %rdi
movq %r13, %rsi
callq 0xedb6
orq %rdx, (%rax)
movb $0x1, %bpl
incq %r13
addq $0x1c, %r12
cmpq %r13, 0xa0(%rsp)
jne 0x5c2a7
testb $0x1, %bpl
movq 0x120(%rsp), %r12
je 0x5c62e
movq %r14, %rbp
movq 0xa0(%rsp), %r13
movq 0x128(%rsp), %r14
incq %r14
cmpq %r13, %r14
jne 0x5c225
xorl %eax, %eax
movq %rax, 0x58(%rsp)
movl %eax, 0x60(%rsp)
movq %rax, 0x68(%rsp)
movl %eax, 0x70(%rsp)
movq %rax, 0x78(%rsp)
testl %r12d, %r12d
jle 0x5c4a8
leaq 0x58(%rsp), %rbx
movl %r12d, %ebp
movq %rbx, %rdi
xorl %esi, %esi
callq 0xe9e6
decl %ebp
jne 0x5c49a
leaq 0x58(%rsp), %rdx
xorl %edi, %edi
movq %r15, %rsi
callq 0xa039f
testl %r12d, %r12d
jle 0x5c4f5
andl $0x7fffffff, %r12d      # imm = 0x7FFFFFFF
xorl %r14d, %r14d
leaq 0x58(%rsp), %r15
movl $0x1, %ebp
xorl %ebx, %ebx
movq %r15, %rdi
movq %r14, %rsi
callq 0xedb6
testq %rdx, (%rax)
movzbl %bl, %ebx
cmovel %ebp, %ebx
incq %r14
cmpq %r12, %r14
jae 0x5c4f7
testb $0x1, %bl
je 0x5c4d2
jmp 0x5c4f7
xorl %ebx, %ebx
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x5c527
movq 0x78(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movq %rax, 0x58(%rsp)
movl %eax, 0x60(%rsp)
movq %rax, 0x68(%rsp)
movl %eax, 0x70(%rsp)
movq %rax, 0x78(%rsp)
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x5c56c
movq 0xd0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movq %rax, 0xb0(%rsp)
movl %eax, 0xb8(%rsp)
movq %rax, 0xc0(%rsp)
movl %eax, 0xc8(%rsp)
movq %rax, 0xd0(%rsp)
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x5c589
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
andb $0x1, %bl
movl %ebx, %eax
addq $0x1d8, %rsp            # imm = 0x1D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xf30fe(%rip), %rdi     # 0x14f6a5
movq %r13, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xf30ed(%rip), %rdi     # 0x14f6a5
movq %r12, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xf30dc(%rip), %rdi     # 0x14f6a5
xorl %eax, %eax
callq 0x4630
leaq 0xf8c13(%rip), %rdi     # 0x1551ea
movq 0x40(%rsp), %rsi
movl %r12d, %edx
xorl %eax, %eax
callq 0x4060
movl $0x1, %edi
callq 0x710c
leaq 0xf30ae(%rip), %rdi     # 0x14f6a5
movq %r13, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xf8d2a(%rip), %rdi     # 0x155332
movl 0x48(%rsp), %esi
movl 0x40(%rsp), %edx
jmp 0x5c5df
leaq 0xf308c(%rip), %rdi     # 0x14f6a5
xorl %eax, %eax
callq 0x4630
leaq 0xf307e(%rip), %rdi     # 0x14f6a5
xorl %eax, %eax
callq 0x4630
leaq 0xf8d4b(%rip), %rdi     # 0x155380
movl 0x48(%rsp), %esi
movl 0x40(%rsp), %edx
movl 0x54(%rsp), %ecx
xorl %eax, %eax
callq 0x4060
jmp 0x5c5e6
leaq 0xf8c48(%rip), %rdi     # 0x155299
movl %r13d, %esi
xorl %eax, %eax
callq 0x4060
jmp 0x5c5e6
jmp 0x5c681
jmp 0x5c6c0
jmp 0x5c6c0
movq %rax, %rbx
jmp 0x5c75d
movq %rax, %rbx
jmp 0x5c740
jmp 0x5c675
movq %rax, %rbx
jmp 0x5c77a
jmp 0x5c6c0
jmp 0x5c681
movq %rax, %rbx
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x5c6c3
movq 0x78(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movq %rax, 0x58(%rsp)
movl %eax, 0x60(%rsp)
movq %rax, 0x68(%rsp)
movl %eax, 0x70(%rsp)
movq %rax, 0x78(%rsp)
jmp 0x5c6c3
jmp 0x5c6c0
jmp 0x5c6c0
jmp 0x5c6c0
jmp 0x5c6c0
jmp 0x5c6c0
movq %rax, %rbx
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x5c77a
movq 0xd0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movq %rax, 0xb0(%rsp)
movl %eax, 0xb8(%rsp)
movq %rax, 0xc0(%rsp)
movl %eax, 0xc8(%rsp)
movq %rax, 0xd0(%rsp)
jmp 0x5c77a
jmp 0x5c718
jmp 0x5c718
jmp 0x5c718
jmp 0x5c718
jmp 0x5c718
movq %rax, %rbx
movq 0x100(%rsp), %rdi
leaq 0x110(%rsp), %rax
cmpq %rax, %rdi
je 0x5c740
movq 0x110(%rsp), %rsi
incq %rsi
callq 0x4470
movq 0xe8(%rsp), %rdi
testq %rdi, %rdi
je 0x5c75d
movq 0xf8(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xd0(%rsp), %rdi
testq %rdi, %rdi
je 0x5c77a
movq 0xe0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x5c797
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq %rbx, %rdi
callq 0x4780