// File: /workspace/github_c_makefile_star2_O3/stanfordnlp[P]GloVe/src/cooccur.c
// Function: main
int main(int argc, char **argv) {
    int i;
    real rlimit, n = 1e5;
    vocab_file = malloc(sizeof(char) * MAX_STRING_LENGTH);
    file_head = malloc(sizeof(char) * MAX_STRING_LENGTH);
    
    if (argc == 1) {
        printf("Tool to calculate word-word cooccurrence statistics\n");
        printf("Author: Jeffrey Pennington (jpennin@stanford.edu)\n\n");
        printf("Usage options:\n");
        printf("\t-verbose <int>\n");
        printf("\t\tSet verbosity: 0, 1, 2 (default), or 3\n");
        printf("\t-symmetric <int>\n");
        printf("\t\tIf <int> = 0, only use left context; if <int> = 1 (default), use left and right\n");
        printf("\t-window-size <int>\n");
        printf("\t\tNumber of context words to the left (and to the right, if symmetric = 1); default 15\n");
        printf("\t-vocab-file <file>\n");
        printf("\t\tFile containing vocabulary (truncated unigram counts, produced by 'vocab_count'); default vocab.txt\n");
        printf("\t-memory <float>\n");
        printf("\t\tSoft limit for memory consumption, in GB -- based on simple heuristic, so not extremely accurate; default 4.0\n");
        printf("\t-max-product <int>\n");
        printf("\t\tLimit the size of dense cooccurrence array by specifying the max product <int> of the frequency counts of the two cooccurring words.\n\t\tThis value overrides that which is automatically produced by '-memory'. Typically only needs adjustment for use with very large corpora.\n");
        printf("\t-overflow-length <int>\n");
        printf("\t\tLimit to length <int> the sparse overflow array, which buffers cooccurrence data that does not fit in the dense array, before writing to disk. \n\t\tThis value overrides that which is automatically produced by '-memory'. Typically only needs adjustment for use with very large corpora.\n");
        printf("\t-overflow-file <file>\n");
        printf("\t\tFilename, excluding extension, for temporary files; default overflow\n");
        printf("\t-distance-weighting <int>\n");
        printf("\t\tIf <int> = 0, do not weight cooccurrence count by distance between words; if <int> = 1 (default), weight the cooccurrence count by inverse of distance between words\n");

        printf("\nExample usage:\n");
        printf("./cooccur -verbose 2 -symmetric 0 -window-size 10 -vocab-file vocab.txt -memory 8.0 -overflow-file tempoverflow < corpus.txt > cooccurrences.bin\n\n");
        free(vocab_file);
        free(file_head);
        return 0;
    }

    if ((i = find_arg((char *)"-verbose", argc, argv)) > 0) verbose = atoi(argv[i + 1]);
    if ((i = find_arg((char *)"-symmetric", argc, argv)) > 0) symmetric = atoi(argv[i + 1]);
    if ((i = find_arg((char *)"-window-size", argc, argv)) > 0) window_size = atoi(argv[i + 1]);
    if ((i = find_arg((char *)"-vocab-file", argc, argv)) > 0) strcpy(vocab_file, argv[i + 1]);
    else strcpy(vocab_file, (char *)"vocab.txt");
    if ((i = find_arg((char *)"-overflow-file", argc, argv)) > 0) strcpy(file_head, argv[i + 1]);
    else strcpy(file_head, (char *)"overflow");
    if ((i = find_arg((char *)"-memory", argc, argv)) > 0) memory_limit = atof(argv[i + 1]);
    if ((i = find_arg((char *)"-distance-weighting", argc, argv)) > 0)  distance_weighting = atoi(argv[i + 1]);
    
    /* The memory_limit determines a limit on the number of elements in bigram_table and the overflow buffer */
    /* Estimate the maximum value that max_product can take so that this limit is still satisfied */
    rlimit = 0.85 * (real)memory_limit * 1073741824/(sizeof(CREC));
    while (fabs(rlimit - n * (log(n) + 0.1544313298)) > 1e-3) n = rlimit / (log(n) + 0.1544313298);
    max_product = (long long) n;
    overflow_length = (long long) rlimit/6; // 0.85 + 1/6 ~= 1
    
    /* Override estimates by specifying limits explicitly on the command line */
    if ((i = find_arg((char *)"-max-product", argc, argv)) > 0) max_product = atoll(argv[i + 1]);
    if ((i = find_arg((char *)"-overflow-length", argc, argv)) > 0) overflow_length = atoll(argv[i + 1]);
    
    const int returned_value = get_cooccurrence();
    free(vocab_file);
    free(file_head);
    return returned_value;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rsi, %rbx
movl %edi, %ebp
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x1170
movq %rax, 0x37c2(%rip)      # 0x6140
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x1170
movq %rax, 0x3799(%rip)      # 0x6128
cmpl $0x1, %ebp
jne 0x2ad1
leaq 0xa3c(%rip), %rdi       # 0x33db
callq 0x1080
leaq 0xa64(%rip), %rdi       # 0x340f
callq 0x1080
leaq 0xa8b(%rip), %rdi       # 0x3442
callq 0x1080
leaq 0xa8e(%rip), %rdi       # 0x3451
callq 0x1080
leaq 0xa92(%rip), %rdi       # 0x3461
callq 0x1080
leaq 0xaaf(%rip), %rdi       # 0x348a
callq 0x1080
leaq 0xab5(%rip), %rdi       # 0x349c
callq 0x1080
leaq 0xafb(%rip), %rdi       # 0x34ee
callq 0x1080
leaq 0xb03(%rip), %rdi       # 0x3502
callq 0x1080
leaq 0xb4e(%rip), %rdi       # 0x3559
callq 0x1080
leaq 0xb56(%rip), %rdi       # 0x356d
callq 0x1080
leaq 0xbb0(%rip), %rdi       # 0x35d3
callq 0x1080
leaq 0xbb5(%rip), %rdi       # 0x35e4
callq 0x1080
leaq 0xc19(%rip), %rdi       # 0x3654
callq 0x1080
leaq 0xc21(%rip), %rdi       # 0x3668
callq 0x1080
leaq 0xd27(%rip), %rdi       # 0x377a
callq 0x1080
leaq 0xd33(%rip), %rdi       # 0x3792
callq 0x1080
leaq 0xe44(%rip), %rdi       # 0x38af
callq 0x1080
leaq 0xe4f(%rip), %rdi       # 0x38c6
callq 0x1080
leaq 0xe8a(%rip), %rdi       # 0x390d
callq 0x1080
leaq 0xe99(%rip), %rdi       # 0x3928
callq 0x1080
leaq 0xf34(%rip), %rdi       # 0x39cf
callq 0x1080
leaq 0xf38(%rip), %rdi       # 0x39df
callq 0x1080
xorl %ebx, %ebx
movq 0x368b(%rip), %rdi      # 0x6140
callq 0x1030
movq 0x3667(%rip), %rdi      # 0x6128
callq 0x1030
movl %ebx, %eax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %rbp
retq
leaq 0xc(%rsp), %r14
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x1c68
movl (%r14), %ebx
jmp 0x2aae