#include <cstdio> #include <iostream> #include <string> #include <vector> #include <map> #include <fstream> #include <sstream> #include "node.h" #include "gate.h" #include "gateAND.h" #include "gateOR.h" #include "gateNOT.h" #include "circuit.h" vector<string> mySplitFunction(const string &s); //run the functions needed to load a circuit (fiorst nodes, then gate) void circuit::load_circuit_from_file(string inFileName) { load_nodes_from_file(inFileName); load_gates_from_file(inFileName); } //Read input file and create all the nodes (putthing them in specific vectors if they are input or output nodes) void circuit::load_nodes_from_file(string inFileName) { //Variables string inputFileString; ifstream myfile (inFileName); if (myfile.is_open()) { while(getline (myfile, inputFileString)) { vector<string> words = mySplitFunction(inputFileString); //split the line into words if (words[0] == "INPUT") { bool first = true; for (string i : words) { if(first){first = false;} //skip first word in the line else { nodes.insert(pair<string, node>(i, node(i))); //create node inputs.push_back(i); //add node to the input vectors } } } else if (words[0] == "OUTPUT") { bool first = true; for (string i : words) { if(first){first = false;} //skip first word in the line else { nodes.insert(pair<string, node>(i, node(i))); //create node outputs.push_back(i); //add node to the output vectors } } } else //gate line, we create node if they don't exist already { bool first = true; for (string i : words) //skip first word in the line { if(first){first = false;} else { if(!nodes.count(i)) //node not created yet (no nodes named like this) { nodes.insert(pair<string, node>(i, node(i))); //create node } } } } } myfile.close(); } else cout<<"Unable to open file"<<endl; } //Read input file and create all the gates void circuit::load_gates_from_file(string inFileName) { //Variables string inputFileString; ifstream myfile (inFileName); if (myfile.is_open()) { while(getline (myfile, inputFileString)) { vector<string> words = mySplitFunction(inputFileString); //split the line into words if (words[0] == "AND") { gates.insert(pair<string, gate*>(inputFileString, new gateAND(inputFileString))); //create gate into the map gates.at(inputFileString)->output = &nodes.at(words[1]); //set the output of the newlmy created gate int skipTwice = 2; for (string i : words) //add the inputs { if (skipTwice){skipTwice--;} //skip the gate type and the ouput else { gates.at(inputFileString)->inputs.push_back(&nodes.at(i)); //add input node } } } else if (words[0] == "OR") { gates.insert(pair<string, gate*>(inputFileString, new gateOR(inputFileString))); //create node gates.at(inputFileString)->output = &nodes.at(words[1]); //set the output of the newlmy created gate int skipTwice = 2; for (string i : words) //add the inputs { if (skipTwice){skipTwice--;} //skip the gate type and the ouput else { gates.at(inputFileString)->inputs.push_back(&nodes.at(i)); //add input node } } } else if (words[0] == "NOT") { gates.insert(pair<string, gate*>(inputFileString, new gateNOT(inputFileString))); //create node gates.at(inputFileString)->output = &nodes.at(words[1]); //set the output of the newlmy created gate gates.at(inputFileString)->inputs.push_back(&nodes.at(words[2])); //set input (single input because not gate) } } myfile.close(); } else cout<<"Unable to open file"<<endl; } //reste the nodes value (actually reste the alreadyComputed variable) void circuit::reset() { for (auto& currentNode : nodes) //for all the nodes { currentNode.second.alreadyComputed = false; //change alreadyComputed to false } } //Read input file and set the values of the input nodes void circuit::load_inputs_from_file(string inFileName) { //Variables string inputFileString; ifstream myfile (inFileName); if (myfile.is_open()) { bool skipFirst = true; while(getline (myfile, inputFileString)) { if (skipFirst){skipFirst = false;} //skip first word in the line else { cout<<"new input will be : "<<inputFileString<<endl; reset(); //reset all nodes for (int i = 0; i<inputs.size(); i++) //loop throught all the input node's names { nodes.at(inputs[i]).setValue(int(inputFileString[i])-48); //find the node in the map using it's name as key, set it's value to the input value (converted int from string) } while(!are_all_outputs_computed()) //as long as all output not computed { compute(); //we compute } for (string outputName : outputs) //for all outputs { nodes.at(outputName).showValue(); //show output values } cout<<endl; } } myfile.close(); } else cout<<"Unable to open file"<<endl; } //Run the compute function of every gate void circuit::compute() { for(pair<string, gate*> currentGate: gates) //loop througbt all the gates { currentGate.second->compute(); //execute their compute method } } //Check if all the output nodes have been computed bool circuit::are_all_outputs_computed() { bool myAns = true; for (string outputName : outputs) //for all outputs { if(!nodes.at(outputName).alreadyComputed) //if the output is not computed { myAns = false; break; } } return myAns; } //Call the showgate method of all gates in the circuit void circuit::showGates() { for(pair<string, gate*> currentGate: gates) //for all the gates { currentGate.second->showValue(); //call their showValue method } } //Split function from https://stackoverflow.com/questions/9435385/split-a-string-using-c11 vector<string> mySplitFunction(const string &s) { stringstream ss(s); string item; vector<string> elems; while (getline(ss, item, ' ')) { elems.push_back(item); // elems.push_back(std::move(item)); } return elems; }