// File: /workspace/github_cpp_makefile_star2_O2/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, 0x78(%rsp)
movq %rdi, %r14
xorpd %xmm0, %xmm0
leaq 0xa0(%rsp), %rax
movapd %xmm0, (%rax)
andq $0x0, 0x10(%rax)
leaq 0x3c0(%rdi), %r12
movq 0x3c8(%rdi), %rax
subq 0x3c0(%rdi), %rax
pushq $0x70
popq %rcx
cqto
idivq %rcx
movslq %eax, %r13
testl %r13d, %r13d
movl $0x0, %eax
cmovgl %r13d, %eax
movq %rax, 0x70(%rsp)
pushq $-0x1
popq %r15
xorl %esi, %esi
cmpq 0x70(%rsp), %rsi
je 0x4466f
movq %r12, %rdi
movq %rsi, 0x58(%rsp)
callq 0x4b63c
leaq 0x178(%rsp), %rdi
movq %rax, %rsi
callq 0x4b65a
movq 0x1a0(%rsp), %rax
subq 0x198(%rsp), %rax
cqto
pushq $0x18
popq %rcx
idivq %rcx
movq %rax, %rcx
testl %ecx, %ecx
movl $0x0, %eax
cmovlel %eax, %ecx
movq %rcx, 0x68(%rsp)
xorl %ebx, %ebx
cmpq 0x68(%rsp), %rbx
je 0x44655
leaq 0x198(%rsp), %rdi
movq %rbx, %rsi
callq 0x4b6d6
movq %rbx, 0x50(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x90(%rsp)
movupd (%rax), %xmm0
movapd %xmm0, 0x80(%rsp)
xorl %ebp, %ebp
movl %r15d, %ebx
cmpq %r13, %rbp
jge 0x44581
cmpl $-0x1, %ebx
jne 0x44581
movq %r12, %rdi
movq %rbp, %rsi
callq 0x4b63c
movsd 0x10(%rax), %xmm0
movups (%rax), %xmm1
movaps %xmm1, 0x140(%rsp)
movsd %xmm0, 0x150(%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x28(%rsp)
movaps 0x140(%rsp), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x10(%rsp)
movapd 0x80(%rsp), %xmm0
movupd %xmm0, (%rsp)
movq %r14, %rdi
callq 0x436e3
testb %al, %al
movl %r15d, %ebx
cmovnel %ebp, %ebx
incq %rbp
jmp 0x44509
cmpl $-0x1, %ebx
je 0x4496d
movslq %ebx, %rsi
movq %r12, %rdi
callq 0x4b63c
movq 0x10(%rax), %rcx
movq %rcx, 0x110(%rsp)
movupd (%rax), %xmm0
movapd %xmm0, 0x100(%rsp)
leaq 0x160(%rsp), %rdi
leaq 0x80(%rsp), %rsi
leaq 0x100(%rsp), %rdx
callq 0x642ae
movsd 0x170(%rsp), %xmm0
callq 0x41e0
cvttsd2si %xmm0, %eax
movl %eax, 0x4c(%rsp)
movsd 0x160(%rsp), %xmm0
movsd %xmm0, 0x60(%rsp)
movsd 0x168(%rsp), %xmm0
callq 0x41e0
cvttsd2si %xmm0, %ebp
movsd 0x60(%rsp), %xmm0
callq 0x41e0
cvttsd2si %xmm0, %r8d
movl 0x4c(%rsp), %eax
movl %eax, (%rsp)
leaq 0xb8(%rsp), %rdi
movq 0x58(%rsp), %rsi
movl %ebx, %edx
movq %rdi, %rbx
movq 0x50(%rsp), %rcx
movl %ebp, %r9d
callq 0x75de6
leaq 0xa0(%rsp), %rdi
movq %rbx, %rsi
callq 0x4bbc6
movq 0x50(%rsp), %rbx
incq %rbx
jmp 0x444cb
leaq 0x178(%rsp), %rdi
callq 0xb1ba
movq 0x58(%rsp), %rsi
incq %rsi
jmp 0x44477
movq 0xa8(%rsp), %rax
subq 0xa0(%rsp), %rax
pushq $0x1c
popq %rcx
cqto
idivq %rcx
movq %rax, %rbx
testb $0x1, %bl
jne 0x449ba
leaq 0x178(%rsp), %r14
andq $0x0, (%r14)
andl $0x0, 0x8(%r14)
andq $0x0, 0x10(%r14)
andl $0x0, 0x18(%r14)
andq $0x0, 0x20(%r14)
xorl %ebp, %ebp
testl %ebx, %ebx
cmovgl %ebx, %ebp
movl %ebp, %r15d
subl $0x1, %r15d
jb 0x446cf
movq %r14, %rdi
xorl %esi, %esi
callq 0xa8f6
jmp 0x446bd
movl %ebp, %r15d
movl %ebx, %ebx
xorl %r12d, %r12d
leaq 0x178(%rsp), %r14
movq %r15, 0x58(%rsp)
cmpq %r15, %r12
je 0x448b1
movq %r14, %rdi
movq %r12, %rsi
callq 0xaba4
testq %rdx, (%rax)
jne 0x448a9
leaq 0xa0(%rsp), %rdi
movq %r12, 0x68(%rsp)
movq %r12, %rsi
callq 0x4b9ca
movl (%rax), %ecx
movl %ecx, 0x50(%rsp)
movl 0x4(%rax), %ecx
movl %ecx, 0x60(%rsp)
movl 0x8(%rax), %ecx
movl %ecx, 0x4c(%rsp)
movupd 0xc(%rax), %xmm0
movapd %xmm0, 0x80(%rsp)
xorl %r15d, %r15d
xorl %ebp, %ebp
cmpq %r15, %rbx
je 0x44895
movq %r14, %rdi
movq %r15, %rsi
callq 0xaba4
testq %rdx, (%rax)
jne 0x4488d
leaq 0xa0(%rsp), %rdi
movq %r15, %rsi
callq 0x4b9ca
movq (%rax), %rcx
movl 0x8(%rax), %r12d
movups 0xc(%rax), %xmm0
movaps %xmm0, 0x100(%rsp)
movl 0x50(%rsp), %eax
movl %eax, 0xe0(%rsp)
movl 0x60(%rsp), %eax
movl %eax, 0xe4(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, 0xe8(%rsp)
movaps 0x80(%rsp), %xmm0
leaq 0xec(%rsp), %rax
movups %xmm0, (%rax)
movq %rcx, 0x120(%rsp)
movl %r12d, 0x128(%rsp)
movaps 0x100(%rsp), %xmm0
leaq 0x12c(%rsp), %rax
movups %xmm0, (%rax)
movups 0x120(%rsp), %xmm0
movups 0x12c(%rsp), %xmm1
movups %xmm1, 0x2c(%rsp)
movups %xmm0, 0x20(%rsp)
movupd 0xe0(%rsp), %xmm0
movups 0xec(%rsp), %xmm1
movups %xmm1, 0xc(%rsp)
movupd %xmm0, (%rsp)
callq 0x7602e
testb %al, %al
je 0x4488d
testb $0x1, %bpl
jne 0x4498d
movl 0x50(%rsp), %eax
movl %eax, 0xb8(%rsp)
movl 0x60(%rsp), %eax
movl %eax, 0xbc(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, 0xc0(%rsp)
movapd 0x80(%rsp), %xmm0
leaq 0xc4(%rsp), %rax
movupd %xmm0, (%rax)
movl %r12d, 0xc4(%rsp)
movq 0x78(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x4bbc6
movq 0x68(%rsp), %rsi
movq %r14, %rdi
callq 0xaba4
orq %rdx, (%rax)
movq %r14, %rdi
movq %r15, %rsi
callq 0xaba4
orq %rdx, (%rax)
movb $0x1, %bpl
incq %r15
jmp 0x4473d
testb $0x1, %bpl
je 0x4499e
movq 0x58(%rsp), %r15
movq 0x68(%rsp), %r12
incq %r12
jmp 0x446e4
leaq 0xb8(%rsp), %rbx
andq $0x0, (%rbx)
andl $0x0, 0x8(%rbx)
andq $0x0, 0x10(%rbx)
andl $0x0, 0x18(%rbx)
andq $0x0, 0x20(%rbx)
movq 0x70(%rsp), %rax
subl $0x1, %eax
movq %rax, 0x70(%rsp)
jb 0x448ea
movq %rbx, %rdi
xorl %esi, %esi
callq 0xa8f6
jmp 0x448cf
leaq 0xb8(%rsp), %rdx
xorl %edi, %edi
movq 0x78(%rsp), %rsi
callq 0x76aba
xorl %ebx, %ebx
leaq 0xb8(%rsp), %r15
xorl %r14d, %r14d
cmpq %r13, %rbx
jge 0x4492d
testb $0x1, %r14b
jne 0x4492d
movq %r15, %rdi
movq %rbx, %rsi
callq 0xaba4
testq %rdx, (%rax)
sete %r14b
incq %rbx
jmp 0x4490b
leaq 0xb8(%rsp), %rdi
callq 0xa976
leaq 0x178(%rsp), %rdi
callq 0xa976
leaq 0xa0(%rsp), %rdi
callq 0x4d716
andb $0x1, %r14b
movl %r14d, %eax
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xbd8c6(%rip), %rdi     # 0x10223a
movq 0x58(%rsp), %rsi
movq 0x50(%rsp), %rdx
xorl %eax, %eax
callq 0x4050
pushq $0x1
popq %rdi
callq 0x524c
leaq 0xbd9ee(%rip), %rdi     # 0x102382
movl 0x50(%rsp), %esi
movl 0x4c(%rsp), %edx
jmp 0x4497e
leaq 0xbda2b(%rip), %rdi     # 0x1023d0
movl 0x50(%rsp), %esi
movl 0x4c(%rsp), %edx
movl 0x60(%rsp), %ecx
xorl %eax, %eax
callq 0x4050
jmp 0x44985
leaq 0xbd928(%rip), %rdi     # 0x1022e9
movl %ebx, %esi
xorl %eax, %eax
callq 0x4050
jmp 0x44985
jmp 0x449d2
jmp 0x449f5
jmp 0x449d2
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0xa976
jmp 0x449f8
jmp 0x449f5
jmp 0x449f5
movq %rax, %rbx
jmp 0x44a1f
jmp 0x449f5
jmp 0x449f5
jmp 0x449f5
jmp 0x449f5
movq %rax, %rbx
leaq 0x178(%rsp), %rdi
callq 0xa976
jmp 0x44a1f
jmp 0x44a0f
jmp 0x44a0f
jmp 0x44a0f
jmp 0x44a0f
movq %rax, %rbx
leaq 0x178(%rsp), %rdi
callq 0xb1ba
leaq 0xa0(%rsp), %rdi
callq 0x4d716
movq %rbx, %rdi
callq 0x4780