<commit_before>/** moses-exec.cc --- 
 *
 * Copyright (C) 2010 OpenCog Foundation
 *
 * Author: <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "moses_exec.h"

#include <opencog/util/numeric.h>
#include <opencog/util/log_prog_name.h>

namespace opencog { namespace moses {

static const unsigned int max_filename_size = 255;

/**
 * Display error message about unspecified combo tree and exit
 */
void unspecified_combo_exit() {
    std::cerr << "error: you must specify which combo tree to learn (option -y)"
              << std::endl;
    exit(1);
}

/**
 * Display error message about unsupported type and exit
 */
void unsupported_type_exit(const type_tree& tt) {
    std::cerr << "error: type " << tt << " currently not supported" << std::endl;
    exit(1);
}
void unsupported_type_exit(type_node type) {
    unsupported_type_exit(type_tree(type));
}

/**
 * Display error message about ill formed combo tree and exit
 */
void illformed_exit(const combo_tree& tr) {
    std::cerr << "error: apparently the combo tree " 
              << tr << "is not well formed" << std::endl;
    exit(1);
}

/**
 * Display error message about unsupported problem and exit
 */
void unsupported_problem_exit(const string& problem) {
    std::cerr << "error: problem " << problem 
              << " unsupported for the moment" << std::endl;
    exit(1);
}

/**
 * Display error message about not recognized combo operator and exist
 */
void not_recognized_combo_operator(const string& ops_str) {
    std::cerr << "error: " << ops_str
              << " is not recognized as combo operator" << std::endl;
    exit(1);
}

/**
 * determine the initial exemplar of a given type
 */
combo_tree type_to_exemplar(type_node type) {
    switch(type) {
    case id::boolean_type: return combo_tree(id::logical_and);
    case id::contin_type: return combo_tree(id::plus);
    case id::ill_formed_type:
        std::cerr << "The data type is incorrect, perhaps it has not been"
                  << " possible to infer it from the input table." << std::endl;
        exit(1);
    default:
        unsupported_type_exit(type);
    }
    return combo_tree();
}

combo_tree ann_exemplar(combo::arity_t arity)
{
    combo_tree ann_tr(ann_type(0, id::ann));
    // ann root
    combo_tree::iterator root_node = ann_tr.begin();
    // output node
    combo_tree::iterator output_node =
        ann_tr.append_child(root_node, ann_type(1, id::ann_node));
    // input nodes
    for (combo::arity_t i = 0; i <= arity; ++i) 
        ann_tr.append_child(output_node, ann_type(i + 2, id::ann_input));
    // input nodes' weights
    ann_tr.append_children(output_node, 0.0, arity + 1);
    
    return ann_tr;
}

/**
 * determine the alphabet size given the type_tree of the problem and
 * the of operator that are ignored
 */
int alphabet_size(const type_tree& tt, const vertex_set ignore_ops)
{
    combo::arity_t arity = type_tree_arity(tt);
    type_node output_type = *type_tree_output_type_tree(tt).begin();
    if (output_type == id::boolean_type) {
        return 3 + arity;
    } else if (output_type == id::contin_type) {
        // set alphabet size, 8 is roughly the number of operators
        // in contin formula, it will have to be adapted
        return 8 + arity - ignore_ops.size();
    } else if (output_type == id::ann_type) {
        return 2 + arity*arity; // to account for hidden neurones, very roughly
    } else {
        unsupported_type_exit(tt);
        return 0;
    }
}

// combo_tree
combo_tree str_to_combo_tree(const string& combo_str) {
    stringstream ss;
    combo_tree tr;
    ss << combo_str;
    ss >> tr;
    return tr;
}

// infer the arity of the problem
combo::arity_t infer_arity(const string& problem,                    
                    unsigned int problem_size,
                    const string& input_table_file,
                    const string& combo_str) {
    if(problem == it || problem == ann_it)
        return dataFileArity(input_table_file);
    else if(problem == cp || problem == ann_cp) {
        if(combo_str.empty())
            unspecified_combo_exit();
        // get the combo_tree and infer its type
        combo_tree tr = str_to_combo_tree(combo_str);
        type_tree tt = infer_type_tree(tr);
        if(is_well_formed(tt)) {
            return type_tree_arity(tt);
        } else {
            illformed_exit(tr);
            return -1;
        }
    } else if(problem == pa || problem == dj || problem == mux) {
        return problem_size;
    } else if(problem == sr) {
        return 1;
    } else {
        unsupported_problem_exit(problem);
        return -1;
    }
}

// returns n such that a = n+2^n
field_set::width_t multiplex_arity(field_set::multiplicity_t a)
{
    field_set::multiplicity_t nearest_arity = 1;
    for (field_set::width_t n = 1; n <= integer_log2(a); ++n) {
        nearest_arity = n + pow2(n);
        if (nearest_arity == a)
            return n;
    }

    // not found, exit (XXX or assert ??)
    std::cerr << "Error: for multiplex the arity " << a
              << " must be equal to n+2^n, but no such n exists."
              << " However, the arity " << nearest_arity << " would work."
              << std::endl;

    exit(1);
    return -1;
}

int moses_exec(int argc, char** argv) { 
    // for(int i = 0; i < argc; ++i)
    //     std::cout << "arg = " << argv[i] << std::endl;

    // program options, see options_description below for their meaning
    unsigned long rand_seed;<commit_msg>fixed arity vs multiplicity confusion in moses_exec<commit_after>/** moses-exec.cc --- 
 *
 * Copyright (C) 2010 OpenCog Foundation
 *
 * Author: <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "moses_exec.h"

#include <opencog/util/numeric.h>
#include <opencog/util/log_prog_name.h>

namespace opencog { namespace moses {

static const unsigned int max_filename_size = 255;

/**
 * Display error message about unspecified combo tree and exit
 */
void unspecified_combo_exit() {
    std::cerr << "error: you must specify which combo tree to learn (option -y)"
              << std::endl;
    exit(1);
}

/**
 * Display error message about unsupported type and exit
 */
void unsupported_type_exit(const type_tree& tt) {
    std::cerr << "error: type " << tt << " currently not supported" << std::endl;
    exit(1);
}
void unsupported_type_exit(type_node type) {
    unsupported_type_exit(type_tree(type));
}

/**
 * Display error message about ill formed combo tree and exit
 */
void illformed_exit(const combo_tree& tr) {
    std::cerr << "error: apparently the combo tree " 
              << tr << "is not well formed" << std::endl;
    exit(1);
}

/**
 * Display error message about unsupported problem and exit
 */
void unsupported_problem_exit(const string& problem) {
    std::cerr << "error: problem " << problem 
              << " unsupported for the moment" << std::endl;
    exit(1);
}

/**
 * Display error message about not recognized combo operator and exist
 */
void not_recognized_combo_operator(const string& ops_str) {
    std::cerr << "error: " << ops_str
              << " is not recognized as combo operator" << std::endl;
    exit(1);
}

/**
 * determine the initial exemplar of a given type
 */
combo_tree type_to_exemplar(type_node type) {
    switch(type) {
    case id::boolean_type: return combo_tree(id::logical_and);
    case id::contin_type: return combo_tree(id::plus);
    case id::ill_formed_type:
        std::cerr << "The data type is incorrect, perhaps it has not been"
                  << " possible to infer it from the input table." << std::endl;
        exit(1);
    default:
        unsupported_type_exit(type);
    }
    return combo_tree();
}

combo_tree ann_exemplar(combo::arity_t arity)
{
    combo_tree ann_tr(ann_type(0, id::ann));
    // ann root
    combo_tree::iterator root_node = ann_tr.begin();
    // output node
    combo_tree::iterator output_node =
        ann_tr.append_child(root_node, ann_type(1, id::ann_node));
    // input nodes
    for (combo::arity_t i = 0; i <= arity; ++i) 
        ann_tr.append_child(output_node, ann_type(i + 2, id::ann_input));
    // input nodes' weights
    ann_tr.append_children(output_node, 0.0, arity + 1);
    
    return ann_tr;
}

/**
 * determine the alphabet size given the type_tree of the problem and
 * the of operator that are ignored
 */
int alphabet_size(const type_tree& tt, const vertex_set ignore_ops)
{
    combo::arity_t arity = type_tree_arity(tt);
    type_node output_type = *type_tree_output_type_tree(tt).begin();
    if (output_type == id::boolean_type) {
        return 3 + arity;
    } else if (output_type == id::contin_type) {
        // set alphabet size, 8 is roughly the number of operators
        // in contin formula, it will have to be adapted
        return 8 + arity - ignore_ops.size();
    } else if (output_type == id::ann_type) {
        return 2 + arity*arity; // to account for hidden neurones, very roughly
    } else {
        unsupported_type_exit(tt);
        return 0;
    }
}

// combo_tree
combo_tree str_to_combo_tree(const string& combo_str) {
    stringstream ss;
    combo_tree tr;
    ss << combo_str;
    ss >> tr;
    return tr;
}

// infer the arity of the problem
combo::arity_t infer_arity(const string& problem,                    
                    unsigned int problem_size,
                    const string& input_table_file,
                    const string& combo_str) {
    if(problem == it || problem == ann_it)
        return dataFileArity(input_table_file);
    else if(problem == cp || problem == ann_cp) {
        if(combo_str.empty())
            unspecified_combo_exit();
        // get the combo_tree and infer its type
        combo_tree tr = str_to_combo_tree(combo_str);
        type_tree tt = infer_type_tree(tr);
        if(is_well_formed(tt)) {
            return type_tree_arity(tt);
        } else {
            illformed_exit(tr);
            return -1;
        }
    } else if(problem == pa || problem == dj || problem == mux) {
        return problem_size;
    } else if(problem == sr) {
        return 1;
    } else {
        unsupported_problem_exit(problem);
        return -1;
    }
}

// returns n such that a = n+2^n
unsigned multiplex_arity(arity_t a)
{
    arity_t nearest_arity = 1;
    for (unsigned n = 1; n <= integer_log2(a); ++n) {
        nearest_arity = n + pow2(n);
        if (nearest_arity == a)
            return n;
    }

    // not found, exit (XXX or assert ??)
    std::cerr << "Error: for multiplex the arity " << a
              << " must be equal to n+2^n, but no such n exists."
              << " However, the arity " << nearest_arity << " would work."
              << std::endl;

    exit(1);
    return -1;
}

int moses_exec(int argc, char** argv) { 
    // for(int i = 0; i < argc; ++i)
    //     std::cout << "arg = " << argv[i] << std::endl;

    // program options, see options_description below for their meaning
    unsigned long rand_seed;
{'fraction_non_alphanumeric': 0.11256671518680253, 'fraction_numerical': 0.007924955523208798, 'mean_word_length': 2.7623973227867356, 'pattern_counts': {'":': 0, '<': 147, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3212920', 'n_tokens_mistral': 3953, 'n_tokens_neox': 3777, 'n_words': 1199}