Sym get_subtree(const Sym& cur, size_t w) { if (w-- == 0) return cur; const SymVec& vec = cur.args(); for (unsigned i = 0; i < vec.size(); ++i) { if (w < vec[i].size()) return get_subtree(vec[i], w); w-=vec[i].size(); } return cur; }
std::pair<Sym,bool> insert_subtree_impl(const Sym& cur, size_t w, const Sym& nw) { if (w-- == 0) return make_pair(nw, !(nw == cur)); const SymVec& vec = cur.args(); std::pair<Sym,bool> result; unsigned i; for (i = 0; i < vec.size(); ++i) { if (w < vec[i].size()) { result = insert_subtree_impl(vec[i], w, nw); if (result.second == false) return std::make_pair(cur, false); // unchanged break; } w -= vec[i].size(); } SymVec newvec = cur.args(); newvec[i] = result.first; return make_pair(Sym(cur.token(), newvec), true); }
/* finds and inserts the full code in a hashmap */ HashMap::iterator find_code(Sym sym, HashMap& map) { HashMap::iterator result = map.find(sym); if (result == map.end()) { // new entry const SymVec& args = sym.args(); vector<string> argstr(args.size()); for (unsigned i = 0; i < args.size(); ++i) { argstr[i] = find_code(args[i], map)->second; } // write out the code const FunDef& fun = get_element(sym.token()); string code = fun.c_print(argstr, vector<string>()); result = map.insert( make_pair(sym, code) ).first; // only want iterator } return result; }
HashMap::iterator find_entry(const Sym& sym, string& str, HashMap& map) { HashMap::iterator result = map.find(sym); if (result == map.end()) { // new entry const SymVec& args = sym.args(); vector<string> argstr(args.size()); for (unsigned i = 0; i < args.size(); ++i) { argstr[i] = find_entry(args[i], str, map)->second; } string var = make_var(map.size()); // map.size(): unique id string code; // write out the code const FunDef& fun = get_element(sym.token()); code = fun.c_print(argstr, vector<string>() ); str += "double " + var + "=" + code + ";\n"; result = map.insert( make_pair(sym, var ) ).first; // only want iterator } return result; }
std::pair<Sym, bool> do_mutate(Sym sym, double p, const LanguageTable& table) { bool changed = false; SymVec args = sym.args(); if (rng.flip(p)) { token_t new_token = table.get_random_function(sym.token(), args.size()); if (new_token != sym.token()) { changed = true; sym = Sym(new_token, args); } } for (unsigned i = 0; i < args.size(); ++i) { std::pair<Sym,bool> r = do_mutate(args[i], p, table); changed |= r.second; if (r.second) args[i] = r.first; } if (changed) return std::make_pair(Sym(sym.token(), args), true); // else return std::make_pair(sym, false); }