void print(Value x) { if (is_nil(x)) prints("nil"); else if (is_eof(x)) printf("#eof"); else if (is_fixnum(x)) printf("%d", as_fixnum(x)); else if (is_bool(x)) printf("%s", as_bool(x) ? "true" : "false"); else if (is_char(x)) printf("'%c'", as_char(x)); else if (is_pair(x)) print_list(x); else if (is_symbol(x)) prints(as_symbol(x)->value); else if (is_string(x)) print_string(as_string(x)); else if (is_procedure(x)) printf("#<procedure %s>", as_procedure(x)->name->value); else if (is_module(x)) printf("#<module>"); else if (is_type(x)) printf("#<type %s>", as_type(x)->name->value); else if (is_ptr(x)) printf("#<object %p>", as_ptr(x)); else if (is_undefined(x)) printf("#undefined"); else printf("#ufo"); }
Block* find_enclosing_module(Block* block) { while (true) { if (block == NULL) return NULL; if (is_module(block)) return block; block = get_parent_block(block); } }
std::string write_realization_settings::type_label( const gate& g ) const { if ( is_toffoli( g ) ) { return boost::str( boost::format( "t%d" ) % g.size() ); } else if ( is_fredkin( g ) ) { return boost::str( boost::format( "f%d" ) % g.size() ); } else if ( is_peres( g ) ) { return "p"; } else if ( is_module( g ) ) { return boost::any_cast<module_tag>( g.type() ).name; } else { return "UNKNOWN"; } }
Term* run_name_search(NameSearch* params) { stat_increment(NameSearch); if (is_null(¶ms->name) || string_equals(¶ms->name, "")) return NULL; Block* block = params->block; if (block == NULL) return NULL; int position = 0; if (is_symbol(¶ms->position) && as_symbol(¶ms->position) == s_last) position = block->length(); else position = as_int(¶ms->position); if (position > block->length()) position = block->length(); // Look for an exact match. for (int i = position - 1; i >= 0; i--) { stat_increment(NameSearchStep); Term* term = block->get(i); if (term == NULL) continue; if (equals(&term->nameValue, ¶ms->name) && fits_lookup_type(term, params->lookupType) && (params->ordinal == -1 || term->uniqueOrdinal == params->ordinal)) return term; // If this term exposes its names, then search inside the nested block. // (Deprecated, I think). if (term->nestedContents != NULL && exposes_nested_names(term)) { NameSearch nestedSearch; nestedSearch.block = term->nestedContents; set_value(&nestedSearch.name, ¶ms->name); set_symbol(&nestedSearch.position, s_last); nestedSearch.ordinal = -1; nestedSearch.lookupType = params->lookupType; nestedSearch.searchParent = false; Term* found = run_name_search(&nestedSearch); if (found != NULL) return found; } #if 0 // Check for an 'import' statement. If found, continue this search in the designated module. if (term->function == FUNCS.require && term->boolProp(s_Syntax_Import, false)) { Block* module = find_module_for_require_statement(term); if (module != NULL) { NameSearch moduleSearch; moduleSearch.block = module; set_value(&moduleSearch.name, ¶ms->name); set_symbol(&moduleSearch.position, s_last); moduleSearch.ordinal = -1; moduleSearch.lookupType = params->lookupType; moduleSearch.searchParent = false; Term* found = run_name_search(&moduleSearch); if (found != NULL) return found; } } #endif } // Did not find in the local block. Possibly continue this search upwards. if (!params->searchParent) return NULL; // Possibly take this search to the builtins block. if ((get_parent_block(block) == NULL) || is_module(block)) { NameSearch builtinsSearch; builtinsSearch.block = find_builtins_block(block); set_value(&builtinsSearch.name, ¶ms->name); set_symbol(&builtinsSearch.position, s_last); builtinsSearch.lookupType = params->lookupType; builtinsSearch.ordinal = -1; builtinsSearch.searchParent = false; return run_name_search(&builtinsSearch); } // Search parent // The choice of position is a little weird. For regular name searches, // we start at the parent term's position (ie, search all the terms that // came before the parent). // // For a LookupFunction search, start at the bottom of the branch. It's okay // for a term to use a function that occurs after the term. NameSearch parentSearch; Term* parentTerm = block->owningTerm; if (parentTerm == NULL) return NULL; parentSearch.block = parentTerm->owningBlock; if (params->lookupType == s_LookupFunction) set_symbol(&parentSearch.position, s_last); else set_int(&parentSearch.position, parentTerm->index + 1); set_value(&parentSearch.name, ¶ms->name); parentSearch.lookupType = params->lookupType; parentSearch.ordinal = -1; parentSearch.searchParent = true; return run_name_search(&parentSearch); }
boost::dynamic_bitset<>& core_gate_simulation::operator()( const gate& g, boost::dynamic_bitset<>& input ) const { if ( is_toffoli( g ) ) { boost::dynamic_bitset<> c_mask( input.size() ); boost::dynamic_bitset<> input_copy = input; for ( const auto& v : g.controls() ) { if ( !v.polarity() ) { input_copy.flip( v.line() ); } c_mask.set( v.line() ); } if ( c_mask.none() || ( ( input_copy & c_mask ) == c_mask ) ) { input.flip( g.targets().front() ); } return input; } // TODO negative controls else if ( is_fredkin( g ) ) { boost::dynamic_bitset<> c_mask( input.size() ); for ( const auto& v : g.controls() ) { assert( v.polarity() ); c_mask.set( v.line() ); } if ( c_mask.none() || ( ( input & c_mask ) == c_mask ) ) { // get both positions and values unsigned t1 = g.targets().at( 0u ); unsigned t2 = g.targets().at( 1u ); bool t1v = input.test( t1 ); bool t2v = input.test( t2 ); // only swap when different if ( t1v != t2v ) { input.set( t1, t2v ); input.set( t2, t1v ); } } return input; } else if ( is_peres( g ) ) { if ( input.test( g.controls().front().line() ) ) // is single control set { // get both positions and value of t1 unsigned t1 = g.targets().at( 0u ); unsigned t2 = g.targets().at( 1u ); bool t1v = input.test( t1 ); /* flip t1 */ input.flip( t1 ); /* flip t2 if t1 was true */ if ( t1v ) { input.flip( t2 ); } } return input; } else if ( is_module( g ) ) { boost::dynamic_bitset<> c_mask( input.size() ); for ( const auto& v : g.controls() ) { assert( v.polarity() ); c_mask.set( v.line() ); } // cancel if controls are not hit if ( !c_mask.is_subset_of( input ) ) { return input; } const module_tag* tag = boost::any_cast<module_tag>( &g.type() ); // TODO write test case // get the new input sub pattern boost::dynamic_bitset<> tpattern( g.targets().size() ); for ( const auto& i : g.targets() ) { tpattern.set( i, input.test( i ) ); } boost::dynamic_bitset<> toutput; assert( simple_simulation( toutput, *tag->reference, tpattern ) ); for ( const auto& i : g.targets() ) { input.set( i, toutput.test( i ) ); } return input; } else { assert( false ); } }
void write_realization( const circuit& circ, std::ostream& os, const write_realization_settings& settings ) { unsigned oldsize = 0; if ( !settings.header.empty() ) { std::string header = settings.header; boost::algorithm::replace_all( header, "\n", "\n# " ); os << "# " << header << std::endl; } if ( !settings.version.empty() ) { os << ".version " << settings.version << std::endl; } os << ".numvars " << circ.lines() << std::endl; std::vector<std::string> variables( circ.lines() ); for ( unsigned i = 0u; i < circ.lines(); ++i ) { variables[i] = boost::str( boost::format( "x%d" ) % i ); } std::vector<std::string> _inputs( circ.inputs().begin(), circ.inputs().end() ); oldsize = _inputs.size(); _inputs.resize( circ.lines() ); for ( unsigned i = oldsize; i < circ.lines(); ++i ) { _inputs[i] = boost::str( boost::format( "i%d" ) % i ); } std::vector<std::string> _outputs( circ.outputs().begin(), circ.outputs().end() ); oldsize = _outputs.size(); _outputs.resize( circ.lines() ); for ( unsigned i = oldsize; i < circ.lines(); ++i ) { _outputs[i] = boost::str( boost::format( "o%d" ) % i ); } os << ".variables " << boost::algorithm::join( variables, " " ) << std::endl; namespace karma = boost::spirit::karma; namespace ascii = boost::spirit::ascii; os << ".inputs"; //std::ostream_iterator<char> outit( os ); //karma::generate_delimited( outit, *( karma::no_delimit['"' << karma::string] << '"' ), ascii::space, _inputs ); for ( const auto& _input : _inputs ) { std::string quote = ( _input.find( " " ) != std::string::npos ) ? "\"" : ""; os << boost::format( " %s%s%s" ) % quote % _input % quote; } os << std::endl; os << ".outputs"; //karma::generate_delimited( outit, *( karma::no_delimit['"' << karma::string] << '"' ), ascii::space, _outputs ); for ( const auto& _output : _outputs ) { std::string quote = ( _output.find( " " ) != std::string::npos ) ? "\"" : ""; os << boost::format( " %s%s%s" ) % quote % _output % quote; } os << std::endl; std::string _constants( circ.lines(), '-' ); std::transform( circ.constants().begin(), circ.constants().end(), _constants.begin(), constant_to_char() ); std::string _garbage( circ.lines(), '-' ); std::transform( circ.garbage().begin(), circ.garbage().end(), _garbage.begin(), garbage_to_char() ); os << ".constants " << _constants << std::endl << ".garbage " << _garbage << std::endl; for ( const auto& bus : circ.inputbuses().buses() ) { std::vector<std::string> lines; std::transform( bus.second.begin(), bus.second.end(), std::back_inserter( lines ), line_to_variable() ); os << ".inputbus " << bus.first << " " << boost::algorithm::join( lines, " " ) << std::endl; } for ( const auto& bus : circ.outputbuses().buses() ) { std::vector<std::string> lines; std::transform( bus.second.begin(), bus.second.end(), std::back_inserter( lines ), line_to_variable() ); os << ".outputbus " << bus.first << " " << boost::algorithm::join( lines, " " ) << std::endl; } for ( const auto& bus : circ.statesignals().buses() ) { std::vector<std::string> lines; std::transform( bus.second.begin(), bus.second.end(), std::back_inserter( lines ), line_to_variable() ); os << ".state " << bus.first << " " << boost::algorithm::join( lines, " " ) << std::endl; } for ( const auto& module : circ.modules() ) { os << ".module " << module.first << std::endl; write_realization_settings module_settings; module_settings.version.clear(); module_settings.header.clear(); write_realization( *module.second, os, module_settings ); } os << ".begin" << std::endl; std::string cmd; for ( const auto& g : circ ) { if ( is_toffoli( g ) ) { cmd = boost::str( boost::format( "t%d" ) % g.size() ); } else if ( is_fredkin( g ) ) { cmd = boost::str( boost::format( "f%d" ) % g.size() ); } else if ( is_peres( g ) ) { cmd = "p"; } else if ( is_module( g ) ) { cmd = boost::any_cast<module_tag>( g.type() ).name; } std::vector<std::string> lines; // Peres is special boost::transform( g.controls(), std::back_inserter( lines ), line_to_variable() ); boost::transform( g.targets(), std::back_inserter( lines ), line_to_variable() ); os << cmd << " " << boost::algorithm::join( lines, " " ); boost::optional<const std::map<std::string, std::string>&> annotations = circ.annotations( g ); if ( annotations ) { std::string sannotations; for ( const auto& p : *annotations ) { sannotations += boost::str( boost::format( " %s=\"%s\"" ) % p.first % p.second ); } os << " #@" << sannotations; } os << std::endl; } os << ".end" << std::endl; }