void GCodeInterpreter::FillTables()
{
	//Format Function, args; args; ...
	ifstream in("gcode.dat");
	string line;
	while(getline(in, line))
	{
		istringstream i(line);
		GFunction f;
		FunctionArguments args;
		i >> f.first >> f.second;
		while(i.good())
		{
			char c;
			vector<char> temp;
			while(i >> c && c != ';')
				temp.push_back(c);
			if(!temp.empty())
				args.push_back(temp);
		}
		orderTable.push_back(f);
		functionPrototypes[f] = args;
	}
	//Converting functions
	FillGTable();
}
GCodeLine GCodeInterpreter::AssignGFuncParams(map<char, vector<float>>& data, GFunction& fun, size_t line)
{
	GCodeLine func;
	func.function = fun;
	func.line = line;
	FunctionArguments args = functionPrototypes[fun];
	if(args.size() == 0)
	{
		//Function with no parameters
		if(fun.second == -1)
			func.data[fun.first] = data[fun.first][0];
		else
			func.data[fun.first] = fun.second;
		return func;
	}
	auto iterator = find_if(args.begin(), args.end(), [&] (vector<char>& a)->bool
	{
		return MatchesArgumentList(a, data);//there are no arguments
	});
	if(iterator == args.end())//Match didn't found, use  previous arguments
		iterator = find_if(args.begin(), args.end(), [&] (vector<char>& a)->bool
		{
			return MatchesArgumentListWithOldVariables(a, data);
		});
	if(iterator == args.end())
		throw exception("Funkci nebyly pøedány správné argumenty");
	//Copy arguments
	if(fun.second == -1)
		func.data[fun.first] = data[fun.first][0];
	else
		func.data[fun.first] = fun.second;
	for_each(iterator->begin(), iterator->end(), [&](char c)
	{
		auto argIter = data.find(c);
		if(argIter != data.end())
		{
			if(argIter->second.size() > 1)
				throw exception("Vícenásobný argument");
			func.data[c] = data[c][0];
			return;
		}
		auto argIter2 = lastValue.find(c);
		if(argIter2 != lastValue.end())
		{
			if(coordType == INC && IsAxis(c))
			{
				func.data[c] = 0;
			}
			else
				func.data[c] = lastValue[c];
			return;
		}
		throw exception("Nebyly pøedány všechny argumenty");
	});
	return func;
}
FunctionArguments<ArgType> simplex(
		const std::vector<Constraint<ArgType>>& constraints,
		const ObjectiveFunction<ArgType, RetType, CoeffType>& function)
{
	if(constraints.size() == 0)
		throw "No constraints";
	if(constraints[0].size() != function.size())
		throw "Size of constraints not equal to function size";
	Matrix<CoeffType> simplexTab(constraints.size() + 1,
			function.size() + constraints.size() + 2);
	unsigned long cols = simplexTab.getColumnsNumber(), rows =
			simplexTab.getRowsNumber(), constrNum = constraints.size(), argsNum =
			function.size();
	generateSimplexTab(constraints, function, simplexTab);
	std::map<unsigned long,unsigned long> slackSwaped;
	while (simplexTab.countIfInRange(rows - 1, 0, rows - 1, cols - 1,
			[](const CoeffType& x)
			{	return x<0;}))
	{
		unsigned long pivotColumn, row;
		simplexTab.findMinimumInRange(rows - 1, 0, rows - 1, cols - 3, row,
				pivotColumn);
		row = findMinInColumnBDiv(simplexTab, pivotColumn);
		slackSwaped[row]=pivotColumn;
		simplexTab.multiplyRow(1/simplexTab(row,pivotColumn),row);
		for(unsigned long j=0;j<rows;j++)
			if(j!=row)
				simplexTab.addRow(-simplexTab(j,pivotColumn),row,j);
	}
	std::cout<<simplexTab;
	FunctionArguments<ArgType> bestSolution;
	bestSolution.size(argsNum);
	for(unsigned long j=0;j<constrNum;j++)
		bestSolution.setArg(slackSwaped[j],simplexTab(j,cols-1));
	return bestSolution;
}