<commit_before>/*
 * File:   main.cpp
 * Author: tziegler
 *
 * Created on 5. November 2015, 12:24
 */

#include <cstdlib>
#include "GetFileDiff.h"
#include <unistd.h>
#include <X11/Xlib.h>
#include "MenuHandle.h"
#include "TermInfo.h"
#include "TermHandle.h"
#include "ScreenHandle.h"

using namespace std;

/*
 *
 */
int main(int argc, char** argv) {
	//string path = "/home/tziegler/Remote/seafight";

	string applyCommands;
	string add = "";
	Bool argumentsGot = false;
	for (int i = 1; i < argc; i++) {
		string str(argv[i]);
		applyCommands += add + str;
		add = ";";
		argumentsGot = true;
	}

	cout << "Git Merging Tool\t" << applyCommands << endl;

	string path = "/home/tziegler/Bigpoint/seafight_Lokal";

	string currentBranch = "master";

	string compareToBrach = "release/release_16.3.1";

	string basePath = "code/presentation/website/";

	TermInfo Terminal;

	string pushCommand = "P";
	string pullCommand = "R";
	string cherryListSchowCommand = "L";
	string markForCherry = "m";

	ScreenHandle::enableColor(true);

	MenuHandle Menu;

	GetFileDiff GitWorker;
	GitWorker.setWorkingDir(path);
	GitWorker.setCheckBranch(compareToBrach);

	Menu.addMenu("change Working directory [" + path + "]", "w");
	Menu.addMenu("Current Branch " + currentBranch, "o");
	Menu.addMenu("Compare Branch " + compareToBrach, "n");
	Menu.addMenu("GIT pull rebase (booth)", pullCommand);
	Menu.addMenu("GIT push (Target)", pushCommand);
	Menu.addMenu("add Author ", "u");
	Menu.addMenu("set Filter", "b");
	Menu.addMenu("...Clear Difflist", "clear");
	Menu.addMenu("...Show Diff Files", "l");
	Menu.addMenu("...Show Cherry List", cherryListSchowCommand);
	Menu.addMenu("...Get Missing Commits", "h");
	Menu.addMenu("...Get Missing and affected", "hh");
	Menu.addMenu("...Mark for CherryPick", markForCherry);
	Menu.addMenu("...Mark All for CherryPick", "ma");
	Menu.addMenu("...Cherrypick", "C");
	Menu.addMenu("...Just Show Cherrypick", "c");
	Menu.addMenu("...Cherrypick marked", "cm");
	Menu.addMenu("Start Reading", "r");

	Menu.setPromot(GitWorker.getCurrentGitBranch());

	Menu.setMenuVisibile("l", false);
	Menu.setMenuVisibile("L", false);
	Menu.setMenuVisibile("h", false);
	Menu.setMenuVisibile("hh", false);
	Menu.setMenuVisibile("c", false);
	Menu.setMenuVisibile("C", false);
	Menu.setMenuVisibile("cm", false);
	Menu.setMenuVisibile("ma", false);
	Menu.setMenuVisibile("m", false);
	Menu.setMenuVisibile("clear", false);

	if (argumentsGot) {
		Menu.setCommandString(applyCommands);
	}

	while (Menu.notDone()) {

		Menu.setPromot(GitWorker.getCurrentGitBranch());
		string option = Menu.showMenu();

		if (option == "clear") {
			GitWorker.clear();
		}

		if (option == "ma") {
			GitWorker.markAll();
		}

		if (option == "cm") {
			GitWorker.runCherryForMarked();
		}

		if (option == "r") {
			GitWorker.getDiffFiles();

		}

		if (option == cherryListSchowCommand) {
			GitWorker.showCherryList();
		}

		if (option == markForCherry) {
			GitWorker.printMissingDiffFiles();
			string number = Menu.getInputString("Insert Number of file:");
			int nr = std::stoi(number);
			GitWorker.markForCherryPick(nr);
		}

		if (option == pullCommand) {
			GitWorker.pullRebase();
		}

		if (option == pushCommand) {
			GitWorker.pushTartget();
		}

		if (option == "l") {
			GitWorker.printDiffFiles();
		}

		if (option == "u") {
			GitWorker.addAuthor();
			GitWorker.getHashes();
			Menu.updateMenu("u", "(" + GitWorker.GetAuthorsAsOnlineString() + ") add Author");

		}

		if (option == "h") {
			GitWorker.getHashes();
			Menu.setMenuVisibile("c", true);
			Menu.setMenuVisibile("C", true);
		}
		if (option == "hh") {
			GitWorker.getHashes(true);
			Menu.setMenuVisibile("c", true);
			Menu.setMenuVisibile("C", true);
		}

		if (option == "C") {
			GitWorker.printMissingDiffFiles();
			string number = Menu.getInputString("Insert Number of file:");
			int nr = std::stoi(number);
			GitWorker.cherryPick(nr);
			GitWorker.clear();
			GitWorker.getDiffFiles();
			GitWorker.getHashes();

			//GitWorker.printCherryPick(nr);
			/*
			Menu.setMenuVisibile("l", false);
			Menu.setMenuVisibile("h", false);
			Menu.setMenuVisibile("c", false);
			 */
		}

		if (option == "c") {
			GitWorker.printMissingDiffFiles();
			string number = Menu.getInputString("Insert Number of file:");
			int nr = std::stoi(number);
			GitWorker.printCherryPick(nr);

		}

		if (option == "w") {
			GitWorker.clear();
			GitWorker.setWorkingDir(Menu.getInputString("working on path"));
			Menu.updateMenu(option, "Working Path is: " + GitWorker.getWorkingDir());
			GitWorker.getDiffFiles();
		}

		if (option == "b") {
			GitWorker.setBasePath(Menu.getInputString("set the base path"));
			Menu.updateMenu(option, "filter: " + GitWorker.getBasePath());
			GitWorker.getDiffFiles();
		}

		if (option == "o") {
			GitWorker.clear();
			GitWorker.setCurrentBranch(Menu.getInputString("set current Branch"));
			Menu.updateMenu(option, "Current Branch: " + GitWorker.getCurrentBranch());
			GitWorker.getDiffFiles();
		}

		if (option == "n") {
			GitWorker.clear();
			GitWorker.setCheckBranch(Menu.getInputString("set Branch for compare"));
			Menu.updateMenu(option, "Compare Branch: " + GitWorker.getCheckBranch());
			GitWorker.getDiffFiles();
		}

		// display options
		if (GitWorker.size() > 0) {
			Menu.setMenuVisibile("l", true);
			Menu.setMenuVisibile("L", true);
			Menu.setMenuVisibile("h", true);
			Menu.setMenuVisibile("hh", true);
			Menu.setMenuVisibile("cm", true);
			Menu.setMenuVisibile("ma", true);
			Menu.setMenuVisibile("clear", true);

		} else {
			Menu.setMenuVisibile("ma", false);
			Menu.setMenuVisibile("cm", false);
			Menu.setMenuVisibile("l", false);
			Menu.setMenuVisibile("L", false);
			Menu.setMenuVisibile("h", false);
			Menu.setMenuVisibile("hh", false);
			Menu.setMenuVisibile("c", false);
			Menu.setMenuVisibile("C", false);
			Menu.setMenuVisibile("clear", false);
		}

	}

	return 0;
}

<commit_msg>coloring optional and disabled at start<commit_after>/*
 * File:   main.cpp
 * Author: tziegler
 *
 * Created on 5. November 2015, 12:24
 */

#include <cstdlib>
#include "GetFileDiff.h"
#include <unistd.h>
#include <X11/Xlib.h>
#include "MenuHandle.h"
#include "TermInfo.h"
#include "TermHandle.h"
#include "ScreenHandle.h"

using namespace std;

void splash() {
	cout << "======================" << endl;
	cout << "Git Cherrypicking Tool" << endl;
	cout << "======================" << endl;

}

/*
 *
 */
int main(int argc, char** argv) {
	//string path = "/home/tziegler/Remote/seafight";

	string applyCommands;
	string add = "";
	Bool argumentsGot = false;
	for (int i = 1; i < argc; i++) {
		string str(argv[i]);
		applyCommands += add + str;
		add = ";";
		argumentsGot = true;
	}

	splash();

	string path = "/home/tziegler/Bigpoint/seafight_Lokal";

	string currentBranch = "master";

	string compareToBrach = "release/release_16.3.1";

	string basePath = "code/presentation/website/";

	TermInfo Terminal;

	string pushCommand = "P";
	string pullCommand = "R";
	string cherryListSchowCommand = "L";
	string markForCherry = "m";

	ScreenHandle::enableColor(false);

	MenuHandle Menu;

	GetFileDiff GitWorker;
	GitWorker.setWorkingDir(path);
	GitWorker.setCheckBranch(compareToBrach);

	Menu.addMenu("change Working directory [" + path + "]", "w");
	Menu.addMenu("Current Branch " + currentBranch, "o");
	Menu.addMenu("Compare Branch " + compareToBrach, "n");
	Menu.addMenu("GIT pull rebase (booth)", pullCommand);
	Menu.addMenu("GIT push (Target)", pushCommand);
	Menu.addMenu("add Author ", "u");
	Menu.addMenu("set Filter", "b");
	Menu.addMenu("...Clear Difflist", "clear");
	Menu.addMenu("...Show Diff Files", "l");
	Menu.addMenu("...Show Cherry List", cherryListSchowCommand);
	Menu.addMenu("...Get Missing Commits", "h");
	Menu.addMenu("...Get Missing and affected", "hh");
	Menu.addMenu("...Mark for CherryPick", markForCherry);
	Menu.addMenu("...Mark All for CherryPick", "ma");
	Menu.addMenu("...Cherrypick", "C");
	Menu.addMenu("...Just Show Cherrypick", "c");
	Menu.addMenu("...Cherrypick marked", "cm");
	Menu.addMenu("Start Reading", "r");
	Menu.addMenu("color on", "coloron");
	Menu.addMenu("color off", "coloroff");

	Menu.setPromot(GitWorker.getCurrentGitBranch());

	Menu.setMenuVisibile("l", false);
	Menu.setMenuVisibile("L", false);
	Menu.setMenuVisibile("h", false);
	Menu.setMenuVisibile("hh", false);
	Menu.setMenuVisibile("c", false);
	Menu.setMenuVisibile("C", false);
	Menu.setMenuVisibile("cm", false);
	Menu.setMenuVisibile("ma", false);
	Menu.setMenuVisibile("m", false);
	Menu.setMenuVisibile("clear", false);

	if (argumentsGot) {
		Menu.setCommandString(applyCommands);
	}

	while (Menu.notDone()) {

		Menu.setPromot(GitWorker.getCurrentGitBranch());
		string option = Menu.showMenu();

		if (option == "coloron") {
			ScreenHandle::enableColor(true);
		}

		if (option == "coloroff") {
			ScreenHandle::enableColor(false);
		}

		if (option == "clear") {
			GitWorker.clear();
		}

		if (option == "ma") {
			GitWorker.markAll();
		}

		if (option == "cm") {
			GitWorker.runCherryForMarked();
		}

		if (option == "r") {
			GitWorker.getDiffFiles();

		}

		if (option == cherryListSchowCommand) {
			GitWorker.showCherryList();
		}

		if (option == markForCherry) {
			GitWorker.printMissingDiffFiles();
			string number = Menu.getInputString("Insert Number of file:");
			int nr = std::stoi(number);
			GitWorker.markForCherryPick(nr);
		}

		if (option == pullCommand) {
			GitWorker.pullRebase();
		}

		if (option == pushCommand) {
			GitWorker.pushTartget();
		}

		if (option == "l") {
			GitWorker.printDiffFiles();
		}

		if (option == "u") {
			GitWorker.addAuthor();
			GitWorker.getHashes();
			Menu.updateMenu("u", "(" + GitWorker.GetAuthorsAsOnlineString() + ") add Author");

		}

		if (option == "h") {
			GitWorker.getHashes();
			Menu.setMenuVisibile("c", true);
			Menu.setMenuVisibile("C", true);
		}
		if (option == "hh") {
			GitWorker.getHashes(true);
			Menu.setMenuVisibile("c", true);
			Menu.setMenuVisibile("C", true);
		}

		if (option == "C") {
			GitWorker.printMissingDiffFiles();
			string number = Menu.getInputString("Insert Number of file:");
			int nr = std::stoi(number);
			GitWorker.cherryPick(nr);
			GitWorker.clear();
			GitWorker.getDiffFiles();
			GitWorker.getHashes();

			//GitWorker.printCherryPick(nr);
			/*
			Menu.setMenuVisibile("l", false);
			Menu.setMenuVisibile("h", false);
			Menu.setMenuVisibile("c", false);
			 */
		}

		if (option == "c") {
			GitWorker.printMissingDiffFiles();
			string number = Menu.getInputString("Insert Number of file:");
			int nr = std::stoi(number);
			GitWorker.printCherryPick(nr);

		}

		if (option == "w") {
			GitWorker.clear();
			GitWorker.setWorkingDir(Menu.getInputString("working on path"));
			Menu.updateMenu(option, "Working Path is: " + GitWorker.getWorkingDir());
			GitWorker.getDiffFiles();
		}

		if (option == "b") {
			GitWorker.setBasePath(Menu.getInputString("set the base path"));
			Menu.updateMenu(option, "filter: " + GitWorker.getBasePath());
			GitWorker.getDiffFiles();
		}

		if (option == "o") {
			GitWorker.clear();
			GitWorker.setCurrentBranch(Menu.getInputString("set current Branch"));
			Menu.updateMenu(option, "Current Branch: " + GitWorker.getCurrentBranch());
			GitWorker.getDiffFiles();
		}

		if (option == "n") {
			GitWorker.clear();
			GitWorker.setCheckBranch(Menu.getInputString("set Branch for compare"));
			Menu.updateMenu(option, "Compare Branch: " + GitWorker.getCheckBranch());
			GitWorker.getDiffFiles();
		}

		// display options
		if (GitWorker.size() > 0) {
			Menu.setMenuVisibile("l", true);
			Menu.setMenuVisibile("L", true);
			Menu.setMenuVisibile("h", true);
			Menu.setMenuVisibile("hh", true);
			Menu.setMenuVisibile("cm", true);
			Menu.setMenuVisibile("ma", true);
			Menu.setMenuVisibile("clear", true);

		} else {
			Menu.setMenuVisibile("ma", false);
			Menu.setMenuVisibile("cm", false);
			Menu.setMenuVisibile("l", false);
			Menu.setMenuVisibile("L", false);
			Menu.setMenuVisibile("h", false);
			Menu.setMenuVisibile("hh", false);
			Menu.setMenuVisibile("c", false);
			Menu.setMenuVisibile("C", false);
			Menu.setMenuVisibile("clear", false);
		}

	}

	return 0;
}

<|endoftext|>


<commit_before>/**
 * \file PancakeInstance.hpp
 *
 *
 *
 * \author eaburns
 * \date 18-01-2010
 */

#if !defined(_PANCAKE_H_)
#define _PANCAKE_H_

#include <boost/array.hpp>
#include <boost/pool/pool.hpp>
#include <boost/utility.hpp>

#include "pancake/PancakeState.hpp"
#include "pancake/PancakeNode.hpp"

#include <iostream>

class PancakeInstance14 : boost::noncopyable
{
public:
	// Number of levels that Rob Holte uses in their paper.
	static const unsigned num_abstraction_levels = 7;

	// Read a 14-pancake instance from an input stream.
	static PancakeInstance14 *read(std::istream &in);

private:
	typedef boost::array<boost::array<bool, 14>,
			     num_abstraction_levels + 1
			     > AbstractionOrder;

	// Create a simple abstraction order that is 7 deep and blanks
	// out one more tile each level.
	static AbstractionOrder
	simple_abstraction_order(const PancakeState14 &);

	// Wrap a child state in a new node.
	PancakeNode14 *child(const PancakeState14 &new_state,
			     PancakeCost new_g,
			     const PancakeNode14 &parent,
			     boost::pool<> &node_pool);

	// Test if pancake number [i] should be abstracted away.
	bool should_abstract(unsigned int level, unsigned int i) const;

public:

	// Create a new pancake puzzle instance
	PancakeInstance14(const PancakeState14 &start,
			  const PancakeState14 &goal);

	// Test if the given state is the goal state.
	inline bool is_goal(const PancakeState14 &s) const {
		return s == goal;
	}

	// Smallest out-edge cost.
	inline PancakeCost get_epsilon(const PancakeState14 &s) const {
		return 1;
	}

	// Compute the successors of the given node.
	//
	// Note that this does not assign the h values for the
	// successor nodes: that must be done by the caller.
	void compute_successors(const PancakeNode14 &n,
				std::vector<PancakeNode14*> &succs,
				boost::pool<> &node_pool);

	// Compute the predecessors of the given node.
	//
	// Note that this does not assign the h values for the
	// successor nodes: that must be done by the caller.
	void compute_predecessors(const PancakeNode14 &n,
				  std::vector<PancakeNode14*> &succs,
				  boost::pool<> &node_pool);

	// Compute/fill-in the heuristic value for a child node.
	void compute_heuristic(const PancakeNode14 &parent,
			       PancakeNode14 &child) const;

	void compute_heuristic(PancakeNode14 &child) const;

	// Access the start state.
	const PancakeState14 &get_start_state() const;

	// Access the goal state.
	const PancakeState14 &get_goal_state() const;

	// Get the abstract representation of a state at the given level.
	PancakeState14 abstract(unsigned int level,
				const PancakeState14 &s) const;

	// Is this level of abstraction valid?
	static bool is_valid_level(const unsigned level) {
		return level <= num_abstraction_levels
			&& level >= 0;
	}

private:
	const PancakeState14 start;
	const PancakeState14 goal;
	const AbstractionOrder abstraction_order;
};

std::ostream &operator<< (std::ostream &, const PancakeInstance14 &);

#endif	// !_PANCAKE_H_
<commit_msg>eliminate vacuously true check in pancakes debug code<commit_after>/**
 * \file PancakeInstance.hpp
 *
 *
 *
 * \author eaburns
 * \date 18-01-2010
 */

#if !defined(_PANCAKE_H_)
#define _PANCAKE_H_

#include <boost/array.hpp>
#include <boost/pool/pool.hpp>
#include <boost/utility.hpp>

#include "pancake/PancakeState.hpp"
#include "pancake/PancakeNode.hpp"

#include <iostream>

class PancakeInstance14 : boost::noncopyable
{
public:
	// Number of levels that Rob Holte uses in their paper.
	static const unsigned num_abstraction_levels = 7;

	// Read a 14-pancake instance from an input stream.
	static PancakeInstance14 *read(std::istream &in);

private:
	typedef boost::array<boost::array<bool, 14>,
			     num_abstraction_levels + 1
			     > AbstractionOrder;

	// Create a simple abstraction order that is 7 deep and blanks
	// out one more tile each level.
	static AbstractionOrder
	simple_abstraction_order(const PancakeState14 &);

	// Wrap a child state in a new node.
	PancakeNode14 *child(const PancakeState14 &new_state,
			     PancakeCost new_g,
			     const PancakeNode14 &parent,
			     boost::pool<> &node_pool);

	// Test if pancake number [i] should be abstracted away.
	bool should_abstract(unsigned int level, unsigned int i) const;

public:

	// Create a new pancake puzzle instance
	PancakeInstance14(const PancakeState14 &start,
			  const PancakeState14 &goal);

	// Test if the given state is the goal state.
	inline bool is_goal(const PancakeState14 &s) const {
		return s == goal;
	}

	// Smallest out-edge cost.
	inline PancakeCost get_epsilon(const PancakeState14 &s) const {
		return 1;
	}

	// Compute the successors of the given node.
	//
	// Note that this does not assign the h values for the
	// successor nodes: that must be done by the caller.
	void compute_successors(const PancakeNode14 &n,
				std::vector<PancakeNode14*> &succs,
				boost::pool<> &node_pool);

	// Compute the predecessors of the given node.
	//
	// Note that this does not assign the h values for the
	// successor nodes: that must be done by the caller.
	void compute_predecessors(const PancakeNode14 &n,
				  std::vector<PancakeNode14*> &succs,
				  boost::pool<> &node_pool);

	// Compute/fill-in the heuristic value for a child node.
	void compute_heuristic(const PancakeNode14 &parent,
			       PancakeNode14 &child) const;

	void compute_heuristic(PancakeNode14 &child) const;

	// Access the start state.
	const PancakeState14 &get_start_state() const;

	// Access the goal state.
	const PancakeState14 &get_goal_state() const;

	// Get the abstract representation of a state at the given level.
	PancakeState14 abstract(unsigned int level,
				const PancakeState14 &s) const;

	// Is this level of abstraction valid?
	static bool is_valid_level(const unsigned level) {
		return level <= num_abstraction_levels;
	}

private:
	const PancakeState14 start;
	const PancakeState14 goal;
	const AbstractionOrder abstraction_order;
};

std::ostream &operator<< (std::ostream &, const PancakeInstance14 &);

#endif	// !_PANCAKE_H_
<|endoftext|>


<commit_before>#include "archive.h"
#include "debug.h"

#include <QThreadPool>

void ParseArchiveListingTask::run()
{
    QVector<File> files;
    QRegExp fileRx("^(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+\\s+\\S+\\s+\\S+)\\s+(.+)$");
    foreach(QString line, _listing.split('\n', QString::SkipEmptyParts))
    {
        if(-1 != fileRx.indexIn(line))
        {
            File file;
            file.mode  = fileRx.capturedTexts()[1];
            file.links = fileRx.capturedTexts()[2].toULongLong();
            file.user  = fileRx.capturedTexts()[3];
            file.group = fileRx.capturedTexts()[4];
            file.size  = fileRx.capturedTexts()[5].toULongLong();
            file.modified = fileRx.capturedTexts()[6];
            file.name     = fileRx.capturedTexts()[7];
            files.append(file);
        }
    }
    emit result(files);
}

Archive::Archive(QObject *parent)
    : QObject(parent),
      _truncated(false),
      _sizeTotal(0),
      _sizeCompressed(0),
      _sizeUniqueTotal(0),
      _sizeUniqueCompressed(0),
      _deleteScheduled(false)
{
}

Archive::~Archive()
{
}

void Archive::save()
{
    bool    exists = doesKeyExist(_name);
    QString queryString;
    if(exists)
        queryString =
            QLatin1String("update archives set name=?, timestamp=?, "
                          "truncated=?, sizeTotal=?, sizeCompressed=?,"
                          " sizeUniqueTotal=?, sizeUniqueCompressed=?, "
                          "command=?, contents=?, jobRef=?"
                          " where name=?");
    else
        queryString = QLatin1String(
            "insert into archives(name, timestamp, truncated, sizeTotal,"
            " sizeCompressed, sizeUniqueTotal, sizeUniqueCompressed, command,"
            " contents, jobRef)"
            " values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(queryString))
    {
        DEBUG << query.lastError().text();
        return;
    }
    query.addBindValue(_name);
    query.addBindValue(_timestamp.toTime_t());
    query.addBindValue(_truncated);
    query.addBindValue(_sizeTotal);
    query.addBindValue(_sizeCompressed);
    query.addBindValue(_sizeUniqueTotal);
    query.addBindValue(_sizeUniqueCompressed);
    query.addBindValue(_command);
    query.addBindValue(_contents);
    query.addBindValue(_jobRef);
    if(exists)
        query.addBindValue(_name);

    store.runQuery(query);
    setObjectKey(_name);
    emit changed();
}

void Archive::load()
{
    if(_name.isEmpty())
    {
        DEBUG << "Attempting to load Archive object with empty _name key.";
        return;
    }
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("select * from archives where name = ?")))
    {
        DEBUG << query.lastError().text();
        return;
    }
    query.addBindValue(_name);
    if(store.runQuery(query) && query.next())
    {
        _timestamp = QDateTime::fromTime_t(
            query.value(query.record().indexOf("timestamp")).toUInt());
        _truncated = query.value(query.record().indexOf("truncated")).toBool();
        _sizeTotal =
            query.value(query.record().indexOf("sizeTotal")).toULongLong();
        _sizeCompressed =
            query.value(query.record().indexOf("sizeCompressed")).toULongLong();
        _sizeUniqueTotal =
            query.value(query.record().indexOf("sizeUniqueTotal")).toULongLong();
        _sizeUniqueCompressed =
            query.value(query.record().indexOf("sizeUniqueCompressed")).toULongLong();
        _command  = query.value(query.record().indexOf("command")).toString();
        _contents = query.value(query.record().indexOf("contents")).toByteArray();
        _jobRef   = query.value(query.record().indexOf("jobRef")).toString();
        setObjectKey(_name);
    }
    else
    {
        DEBUG << "Archive object with key " << _name << " not found.";
    }
}

void Archive::purge()
{
    if(_name.isEmpty())
    {
        DEBUG << "Attempting to delete Archive object with empty _name key.";
        return;
    }
    if(!doesKeyExist(_name))
    {
        DEBUG << "No Archive object with key " << _name;
        return;
    }
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("delete from archives where name = ?")))
    {
        DEBUG << query.lastError().text();
        return;
    }
    query.addBindValue(_name);
    store.runQuery(query);
    setObjectKey("");
    emit purged();
}

bool Archive::doesKeyExist(QString key)
{
    bool found = false;
    if(key.isEmpty())
    {
        DEBUG << "doesKeyExist method called with empty args";
        return found;
    }
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(
           QLatin1String("select name from archives where name = ?")))
    {
        DEBUG << query.lastError().text();
        return found;
    }
    query.addBindValue(key);
    if(store.runQuery(query) && query.next())
    {
        found = true;
    }
    return found;
}

QString Archive::archiveStats()
{
    QString stats;
    if((_sizeTotal == 0) || (_sizeUniqueCompressed == 0))
        return stats;
    stats.append(tr("\t\tTotal size\tCompressed size\n"
                    "this archive\t%1\t\t%2\n"
                    "unique data\t%3\t\t%4")
                     .arg(_sizeTotal)
                     .arg(_sizeCompressed)
                     .arg(_sizeUniqueTotal)
                     .arg(_sizeUniqueCompressed));
    return stats;
}

bool Archive::deleteScheduled() const
{
    return _deleteScheduled;
}

void Archive::setDeleteScheduled(bool deleteScheduled)
{
    _deleteScheduled = deleteScheduled;
    emit changed();
}

bool Archive::truncated() const
{
    return _truncated;
}

void Archive::setTruncated(bool truncated)
{
    _truncated = truncated;
}

QString Archive::jobRef() const
{
    return _jobRef;
}

void Archive::setJobRef(const QString &jobRef)
{
    _jobRef = jobRef;
}

void Archive::getFileList()
{
    QThreadPool *threadPool = QThreadPool::globalInstance();
    ParseArchiveListingTask *parseTask = new ParseArchiveListingTask(contents());
    parseTask->setAutoDelete(true);
    connect(parseTask, &ParseArchiveListingTask::result, this,
            &Archive::fileList);
    threadPool->start(parseTask);
}

bool Archive::hasPreservePaths()
{
    return _command.contains(" -P ", Qt::CaseSensitive);
}

QString Archive::contents() const
{
    return qUncompress(_contents);
}

void Archive::setContents(const QString &value)
{
    _contents = qCompress(value.toLatin1());
}

QString Archive::command() const
{
    return _command;
}

void Archive::setCommand(const QString &value)
{
    _command = value;
}

quint64 Archive::sizeUniqueCompressed() const
{
    return _sizeUniqueCompressed;
}

void Archive::setSizeUniqueCompressed(const quint64 &value)
{
    _sizeUniqueCompressed = value;
}

quint64 Archive::sizeUniqueTotal() const
{
    return _sizeUniqueTotal;
}

void Archive::setSizeUniqueTotal(const quint64 &value)
{
    _sizeUniqueTotal = value;
}

quint64 Archive::sizeCompressed() const
{
    return _sizeCompressed;
}

void Archive::setSizeCompressed(const quint64 &value)
{
    _sizeCompressed = value;
}

quint64 Archive::sizeTotal() const
{
    return _sizeTotal;
}

void Archive::setSizeTotal(const quint64 &value)
{
    _sizeTotal = value;
}

QDateTime Archive::timestamp() const
{
    return _timestamp;
}

void Archive::setTimestamp(const QDateTime &value)
{
    _timestamp = value;
}

QString Archive::name() const
{
    return _name;
}

void Archive::setName(const QString &value)
{
    _name = value;
}
<commit_msg>Archive: comment<commit_after>#include "archive.h"
#include "debug.h"

#include <QThreadPool>

void ParseArchiveListingTask::run()
{
    QVector<File> files;
    // This splits each line of "tarsnap -tv -f ..." into a QStringList.
    // (We don't actually run "tarsnap -tv", because that data is
    // already stored in the Archive _contents when we created it.)
    QRegExp fileRx("^(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+\\s+\\S+\\s+\\S+)\\s+(.+)$");
    foreach(QString line, _listing.split('\n', QString::SkipEmptyParts))
    {
        if(-1 != fileRx.indexIn(line))
        {
            File file;
            file.mode  = fileRx.capturedTexts()[1];
            file.links = fileRx.capturedTexts()[2].toULongLong();
            file.user  = fileRx.capturedTexts()[3];
            file.group = fileRx.capturedTexts()[4];
            file.size  = fileRx.capturedTexts()[5].toULongLong();
            file.modified = fileRx.capturedTexts()[6];
            file.name     = fileRx.capturedTexts()[7];
            files.append(file);
        }
    }
    emit result(files);
}

Archive::Archive(QObject *parent)
    : QObject(parent),
      _truncated(false),
      _sizeTotal(0),
      _sizeCompressed(0),
      _sizeUniqueTotal(0),
      _sizeUniqueCompressed(0),
      _deleteScheduled(false)
{
}

Archive::~Archive()
{
}

void Archive::save()
{
    bool    exists = doesKeyExist(_name);
    QString queryString;
    // Prepare query: either updating or creating an entry.
    if(exists)
        queryString =
            QLatin1String("update archives set name=?, timestamp=?, "
                          "truncated=?, sizeTotal=?, sizeCompressed=?,"
                          " sizeUniqueTotal=?, sizeUniqueCompressed=?, "
                          "command=?, contents=?, jobRef=?"
                          " where name=?");
    else
        queryString = QLatin1String(
            "insert into archives(name, timestamp, truncated, sizeTotal,"
            " sizeCompressed, sizeUniqueTotal, sizeUniqueCompressed, command,"
            " contents, jobRef)"
            " values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
    // Get database instance and create query object.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(queryString))
    {
        DEBUG << query.lastError().text();
        return;
    }
    // Fill in missing values in query string.
    query.addBindValue(_name);
    query.addBindValue(_timestamp.toTime_t());
    query.addBindValue(_truncated);
    query.addBindValue(_sizeTotal);
    query.addBindValue(_sizeCompressed);
    query.addBindValue(_sizeUniqueTotal);
    query.addBindValue(_sizeUniqueCompressed);
    query.addBindValue(_command);
    query.addBindValue(_contents);
    query.addBindValue(_jobRef);
    if(exists)
        query.addBindValue(_name);
    // Run query.
    store.runQuery(query);
    setObjectKey(_name);
    emit changed();
}

void Archive::load()
{
    // Sanity check.
    if(_name.isEmpty())
    {
        DEBUG << "Attempting to load Archive object with empty _name key.";
        return;
    }
    // Get database instance and prepare query.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("select * from archives where name = ?")))
    {
        DEBUG << query.lastError().text();
        return;
    }
    // Fill in missing value in query string.
    query.addBindValue(_name);
    // Run query and extract information.
    if(store.runQuery(query) && query.next())
    {
        _timestamp = QDateTime::fromTime_t(
            query.value(query.record().indexOf("timestamp")).toUInt());
        _truncated = query.value(query.record().indexOf("truncated")).toBool();
        _sizeTotal =
            query.value(query.record().indexOf("sizeTotal")).toULongLong();
        _sizeCompressed =
            query.value(query.record().indexOf("sizeCompressed")).toULongLong();
        _sizeUniqueTotal =
            query.value(query.record().indexOf("sizeUniqueTotal")).toULongLong();
        _sizeUniqueCompressed =
            query.value(query.record().indexOf("sizeUniqueCompressed")).toULongLong();
        _command  = query.value(query.record().indexOf("command")).toString();
        _contents = query.value(query.record().indexOf("contents")).toByteArray();
        _jobRef   = query.value(query.record().indexOf("jobRef")).toString();
        setObjectKey(_name);
    }
    else
    {
        DEBUG << "Archive object with key " << _name << " not found.";
    }
}

void Archive::purge()
{
    // Sanity checks.
    if(_name.isEmpty())
    {
        DEBUG << "Attempting to delete Archive object with empty _name key.";
        return;
    }
    if(!doesKeyExist(_name))
    {
        DEBUG << "No Archive object with key " << _name;
        return;
    }
    // Get database instance and prepare query.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("delete from archives where name = ?")))
    {
        DEBUG << query.lastError().text();
        return;
    }
    // Fill in missing value in query string.
    query.addBindValue(_name);
    // Run query.
    store.runQuery(query);
    setObjectKey("");
    emit purged();
}

bool Archive::doesKeyExist(QString key)
{
    bool found = false;
    // Sanity check.
    if(key.isEmpty())
    {
        DEBUG << "doesKeyExist method called with empty args";
        return found;
    }
    // Get database instance and prepare query.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(
           QLatin1String("select name from archives where name = ?")))
    {
        DEBUG << query.lastError().text();
        return found;
    }
    // Fill in missing value in query string.
    query.addBindValue(key);
    // Run query.
    if(store.runQuery(query) && query.next())
    {
        found = true;
    }
    return found;
}

QString Archive::archiveStats()
{
    QString stats;
    if((_sizeTotal == 0) || (_sizeUniqueCompressed == 0))
        return stats;
    stats.append(tr("\t\tTotal size\tCompressed size\n"
                    "this archive\t%1\t\t%2\n"
                    "unique data\t%3\t\t%4")
                     .arg(_sizeTotal)
                     .arg(_sizeCompressed)
                     .arg(_sizeUniqueTotal)
                     .arg(_sizeUniqueCompressed));
    return stats;
}

bool Archive::deleteScheduled() const
{
    return _deleteScheduled;
}

void Archive::setDeleteScheduled(bool deleteScheduled)
{
    _deleteScheduled = deleteScheduled;
    emit changed();
}

bool Archive::truncated() const
{
    return _truncated;
}

void Archive::setTruncated(bool truncated)
{
    _truncated = truncated;
}

QString Archive::jobRef() const
{
    return _jobRef;
}

void Archive::setJobRef(const QString &jobRef)
{
    _jobRef = jobRef;
}

void Archive::getFileList()
{
    // Prepare a background thread to parse the Archive's saved contents.
    QThreadPool *threadPool = QThreadPool::globalInstance();
    ParseArchiveListingTask *parseTask = new ParseArchiveListingTask(contents());
    parseTask->setAutoDelete(true);
    connect(parseTask, &ParseArchiveListingTask::result, this,
            &Archive::fileList);
    threadPool->start(parseTask);
}

bool Archive::hasPreservePaths()
{
    return _command.contains(" -P ", Qt::CaseSensitive);
}

QString Archive::contents() const
{
    return qUncompress(_contents);
}

void Archive::setContents(const QString &value)
{
    _contents = qCompress(value.toLatin1());
}

QString Archive::command() const
{
    return _command;
}

void Archive::setCommand(const QString &value)
{
    _command = value;
}

quint64 Archive::sizeUniqueCompressed() const
{
    return _sizeUniqueCompressed;
}

void Archive::setSizeUniqueCompressed(const quint64 &value)
{
    _sizeUniqueCompressed = value;
}

quint64 Archive::sizeUniqueTotal() const
{
    return _sizeUniqueTotal;
}

void Archive::setSizeUniqueTotal(const quint64 &value)
{
    _sizeUniqueTotal = value;
}

quint64 Archive::sizeCompressed() const
{
    return _sizeCompressed;
}

void Archive::setSizeCompressed(const quint64 &value)
{
    _sizeCompressed = value;
}

quint64 Archive::sizeTotal() const
{
    return _sizeTotal;
}

void Archive::setSizeTotal(const quint64 &value)
{
    _sizeTotal = value;
}

QDateTime Archive::timestamp() const
{
    return _timestamp;
}

void Archive::setTimestamp(const QDateTime &value)
{
    _timestamp = value;
}

QString Archive::name() const
{
    return _name;
}

void Archive::setName(const QString &value)
{
    _name = value;
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2009, Markus Rickert
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//

#include "Kinematic.h"
#include "NloptInverseKinematics.h"

namespace rl
{
	namespace mdl
	{
		NloptInverseKinematics::NloptInverseKinematics(Kinematic* kinematic) :
			IterativeInverseKinematics(kinematic),
			lb(this->kinematic->getMinimum()),
			opt(::nlopt_create(::NLOPT_LD_SLSQP, kinematic->getDofPosition()), ::nlopt_destroy),
			randDistribution(0, 1),
			randEngine(::std::random_device()()),
			ub(this->kinematic->getMaximum())
		{
			Exception::check(::nlopt_set_ftol_abs(opt.get(), ::std::numeric_limits<double>::epsilon()));
			Exception::check(::nlopt_set_ftol_rel(opt.get(), ::std::numeric_limits<double>::epsilon()));
			Exception::check(::nlopt_set_lower_bounds(opt.get(), this->lb.data()));
			Exception::check(::nlopt_set_min_objective(opt.get(), &NloptInverseKinematics::f, this));
			Exception::check(::nlopt_set_stopval(opt.get(), ::std::pow(this->getEpsilon(), 2)));
			Exception::check(::nlopt_set_upper_bounds(opt.get(), this->ub.data()));
			Exception::check(::nlopt_set_xtol_abs1(opt.get(), ::std::numeric_limits<double>::epsilon()));
			Exception::check(::nlopt_set_xtol_rel(opt.get(), ::std::numeric_limits<double>::epsilon()));
		}

		NloptInverseKinematics::~NloptInverseKinematics()
		{
		}

		double
		NloptInverseKinematics::f(unsigned int n, const double* x, double* grad, void* data)
		{
			NloptInverseKinematics* ik = static_cast<NloptInverseKinematics*>(data);
			++ik->iteration;

			::Eigen::Map<const ::Eigen::VectorXd> q(x, n, 1);

			if (!q.allFinite())
			{
				return ::std::numeric_limits<double>::infinity();
			}

			ik->kinematic->setPosition(q);
			ik->kinematic->forwardPosition();

			::rl::math::Vector dx = ::rl::math::Vector::Zero(6 * ik->kinematic->getOperationalDof());

			for (::std::size_t i = 0; i < ik->goals.size(); ++i)
			{
				::rl::math::VectorBlock dxi = dx.segment(6 * ik->goals[i].second, 6);
				dxi = ik->kinematic->getOperationalPosition(ik->goals[i].second).toDelta(ik->goals[i].first);
			}

			if (nullptr != grad)
			{
				::Eigen::Map< ::Eigen::VectorXd> grad2(grad, n, 1);
				ik->kinematic->calculateJacobian();
				grad2 = -2 * ik->kinematic->getJacobian().transpose() * dx;
			}

			return dx.squaredNorm();
		}

		::rl::math::Real
		NloptInverseKinematics::getFunctionToleranceAbsolute() const
		{
			return ::nlopt_get_ftol_abs(this->opt.get());
		}

		::rl::math::Real
		NloptInverseKinematics::getFunctionToleranceRelative() const
		{
			return ::nlopt_get_ftol_rel(this->opt.get());
		}

		const ::rl::math::Vector&
		NloptInverseKinematics::getLowerBound() const
		{
			return this->lb;
		}

		::rl::math::Vector
		NloptInverseKinematics::getOptimizationToleranceAbsolute() const
		{
			::rl::math::Vector tol;
			Exception::check(::nlopt_get_xtol_abs(this->opt.get(), tol.data()));
			return tol;
		}

		::rl::math::Real
		NloptInverseKinematics::getOptimizationToleranceRelative() const
		{
			return ::nlopt_get_xtol_rel(this->opt.get());
		}

		const ::rl::math::Vector&
		NloptInverseKinematics::getUpperBound() const
		{
			return this->ub;
		}

		void
		NloptInverseKinematics::seed(const ::std::mt19937::result_type& value)
		{
			this->randEngine.seed(value);
		}

		void
		NloptInverseKinematics::setEpsilon(const::rl::math::Real& epsilon)
		{
			Exception::check(::nlopt_set_stopval(opt.get(), ::std::pow(epsilon, 2)));
			IterativeInverseKinematics::setEpsilon(epsilon);
		}

		void
		NloptInverseKinematics::setFunctionToleranceAbsolute(const ::rl::math::Real& functionToleranceAbsolute)
		{
			Exception::check(::nlopt_set_ftol_abs(opt.get(), functionToleranceAbsolute));
		}

		void
		NloptInverseKinematics::setFunctionToleranceRelative(const ::rl::math::Real& functionToleranceRelative)
		{
			Exception::check(::nlopt_set_ftol_rel(opt.get(), functionToleranceRelative));
		}

		void
		NloptInverseKinematics::setLowerBound(const ::rl::math::Vector& lb)
		{
			Exception::check(::nlopt_set_lower_bounds(opt.get(), lb.data()));
			this->lb = lb;
		}

		void
		NloptInverseKinematics::setOptimizationToleranceAbsolute(const ::rl::math::Real& optimizationToleranceAbsolute)
		{
			Exception::check(::nlopt_set_xtol_abs1(opt.get(), optimizationToleranceAbsolute));
		}

		void
		NloptInverseKinematics::setOptimizationToleranceAbsolute(const ::rl::math::Vector& optimizationToleranceAbsolute)
		{
			Exception::check(::nlopt_set_xtol_abs(opt.get(), optimizationToleranceAbsolute.data()));
		}

		void
		NloptInverseKinematics::setOptimizationToleranceRelative(const ::rl::math::Real& optimizationToleranceRelative)
		{
			Exception::check(::nlopt_set_xtol_rel(opt.get(), optimizationToleranceRelative));
		}

		void
		NloptInverseKinematics::setUpperBound(const ::rl::math::Vector& ub)
		{
			Exception::check(::nlopt_set_upper_bounds(opt.get(), ub.data()));
			this->ub = ub;
		}

		bool
		NloptInverseKinematics::solve()
		{
			::std::chrono::steady_clock::time_point start = ::std::chrono::steady_clock::now();
			double remaining = ::std::chrono::duration<double>(this->getDuration()).count();
			this->iteration = 0;

			::rl::math::Vector rand(this->kinematic->getDof());
			::rl::math::Vector q = this->kinematic->getPosition();
			double optF;

			do
			{
				if (::nlopt_set_maxeval(opt.get(), this->getIterations() - this->iteration) < 0)
				{
					return false;
				}

				if (::nlopt_set_maxtime(opt.get(), remaining) < 0)
				{
					return false;
				}

				::nlopt_result result = ::nlopt_optimize(opt.get(), q.data(), &optF);

				if (::NLOPT_STOPVAL_REACHED == result)
				{
					return true;
				}
				else if (result < -1)
				{
					return false;
				}

				for (::std::size_t i = 0; i < this->kinematic->getDof(); ++i)
				{
					rand(i) = this->randDistribution(this->randEngine);
				}

				q = this->kinematic->generatePositionUniform(rand, this->lb, this->ub);

				remaining = ::std::chrono::duration<double>(this->getDuration() - (::std::chrono::steady_clock::now() - start)).count();
			}
			while (remaining > 0 && this->iteration < this->getIterations());

			return false;
		}

		NloptInverseKinematics::Exception::Exception(const ::nlopt_result& result) :
			::rl::mdl::Exception(::std::string()),
			result(result)
		{
		}

		NloptInverseKinematics::Exception::~Exception() throw()
		{
		}

		void
		NloptInverseKinematics::Exception::check(const ::nlopt_result& result)
		{
			if (result < 0)
			{
				throw Exception(result);
			}
		}

		::nlopt_result
		NloptInverseKinematics::Exception::getResult() const
		{
			return this->result;
		}

		const char*
		NloptInverseKinematics::Exception::what() const throw()
		{
			switch (this->result)
			{
			case ::NLOPT_FAILURE:
				return "Generic failure.";
				break;
			case ::NLOPT_INVALID_ARGS:
				return "Invalid arguments.";
				break;
			case ::NLOPT_OUT_OF_MEMORY:
				return "Out of memory.";
				break;
			case ::NLOPT_ROUNDOFF_LIMITED:
				return "Halted because roundoff errors limited progress.";
				break;
			case ::NLOPT_FORCED_STOP:
				return "Halted because of a forced termination.";
				break;
			default:
				return "Unknown error.";
				break;
			}
		}
	}
}
<commit_msg>Initialize vector length<commit_after>//
// Copyright (c) 2009, Markus Rickert
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//

#include "Kinematic.h"
#include "NloptInverseKinematics.h"

namespace rl
{
	namespace mdl
	{
		NloptInverseKinematics::NloptInverseKinematics(Kinematic* kinematic) :
			IterativeInverseKinematics(kinematic),
			lb(this->kinematic->getMinimum()),
			opt(::nlopt_create(::NLOPT_LD_SLSQP, kinematic->getDofPosition()), ::nlopt_destroy),
			randDistribution(0, 1),
			randEngine(::std::random_device()()),
			ub(this->kinematic->getMaximum())
		{
			Exception::check(::nlopt_set_ftol_abs(opt.get(), ::std::numeric_limits<double>::epsilon()));
			Exception::check(::nlopt_set_ftol_rel(opt.get(), ::std::numeric_limits<double>::epsilon()));
			Exception::check(::nlopt_set_lower_bounds(opt.get(), this->lb.data()));
			Exception::check(::nlopt_set_min_objective(opt.get(), &NloptInverseKinematics::f, this));
			Exception::check(::nlopt_set_stopval(opt.get(), ::std::pow(this->getEpsilon(), 2)));
			Exception::check(::nlopt_set_upper_bounds(opt.get(), this->ub.data()));
			Exception::check(::nlopt_set_xtol_abs1(opt.get(), ::std::numeric_limits<double>::epsilon()));
			Exception::check(::nlopt_set_xtol_rel(opt.get(), ::std::numeric_limits<double>::epsilon()));
		}

		NloptInverseKinematics::~NloptInverseKinematics()
		{
		}

		double
		NloptInverseKinematics::f(unsigned int n, const double* x, double* grad, void* data)
		{
			NloptInverseKinematics* ik = static_cast<NloptInverseKinematics*>(data);
			++ik->iteration;

			::Eigen::Map<const ::Eigen::VectorXd> q(x, n, 1);

			if (!q.allFinite())
			{
				return ::std::numeric_limits<double>::infinity();
			}

			ik->kinematic->setPosition(q);
			ik->kinematic->forwardPosition();

			::rl::math::Vector dx = ::rl::math::Vector::Zero(6 * ik->kinematic->getOperationalDof());

			for (::std::size_t i = 0; i < ik->goals.size(); ++i)
			{
				::rl::math::VectorBlock dxi = dx.segment(6 * ik->goals[i].second, 6);
				dxi = ik->kinematic->getOperationalPosition(ik->goals[i].second).toDelta(ik->goals[i].first);
			}

			if (nullptr != grad)
			{
				::Eigen::Map< ::Eigen::VectorXd> grad2(grad, n, 1);
				ik->kinematic->calculateJacobian();
				grad2 = -2 * ik->kinematic->getJacobian().transpose() * dx;
			}

			return dx.squaredNorm();
		}

		::rl::math::Real
		NloptInverseKinematics::getFunctionToleranceAbsolute() const
		{
			return ::nlopt_get_ftol_abs(this->opt.get());
		}

		::rl::math::Real
		NloptInverseKinematics::getFunctionToleranceRelative() const
		{
			return ::nlopt_get_ftol_rel(this->opt.get());
		}

		const ::rl::math::Vector&
		NloptInverseKinematics::getLowerBound() const
		{
			return this->lb;
		}

		::rl::math::Vector
		NloptInverseKinematics::getOptimizationToleranceAbsolute() const
		{
			::rl::math::Vector tol(this->kinematic->getDofPosition());
			Exception::check(::nlopt_get_xtol_abs(this->opt.get(), tol.data()));
			return tol;
		}

		::rl::math::Real
		NloptInverseKinematics::getOptimizationToleranceRelative() const
		{
			return ::nlopt_get_xtol_rel(this->opt.get());
		}

		const ::rl::math::Vector&
		NloptInverseKinematics::getUpperBound() const
		{
			return this->ub;
		}

		void
		NloptInverseKinematics::seed(const ::std::mt19937::result_type& value)
		{
			this->randEngine.seed(value);
		}

		void
		NloptInverseKinematics::setEpsilon(const::rl::math::Real& epsilon)
		{
			Exception::check(::nlopt_set_stopval(opt.get(), ::std::pow(epsilon, 2)));
			IterativeInverseKinematics::setEpsilon(epsilon);
		}

		void
		NloptInverseKinematics::setFunctionToleranceAbsolute(const ::rl::math::Real& functionToleranceAbsolute)
		{
			Exception::check(::nlopt_set_ftol_abs(opt.get(), functionToleranceAbsolute));
		}

		void
		NloptInverseKinematics::setFunctionToleranceRelative(const ::rl::math::Real& functionToleranceRelative)
		{
			Exception::check(::nlopt_set_ftol_rel(opt.get(), functionToleranceRelative));
		}

		void
		NloptInverseKinematics::setLowerBound(const ::rl::math::Vector& lb)
		{
			Exception::check(::nlopt_set_lower_bounds(opt.get(), lb.data()));
			this->lb = lb;
		}

		void
		NloptInverseKinematics::setOptimizationToleranceAbsolute(const ::rl::math::Real& optimizationToleranceAbsolute)
		{
			Exception::check(::nlopt_set_xtol_abs1(opt.get(), optimizationToleranceAbsolute));
		}

		void
		NloptInverseKinematics::setOptimizationToleranceAbsolute(const ::rl::math::Vector& optimizationToleranceAbsolute)
		{
			Exception::check(::nlopt_set_xtol_abs(opt.get(), optimizationToleranceAbsolute.data()));
		}

		void
		NloptInverseKinematics::setOptimizationToleranceRelative(const ::rl::math::Real& optimizationToleranceRelative)
		{
			Exception::check(::nlopt_set_xtol_rel(opt.get(), optimizationToleranceRelative));
		}

		void
		NloptInverseKinematics::setUpperBound(const ::rl::math::Vector& ub)
		{
			Exception::check(::nlopt_set_upper_bounds(opt.get(), ub.data()));
			this->ub = ub;
		}

		bool
		NloptInverseKinematics::solve()
		{
			::std::chrono::steady_clock::time_point start = ::std::chrono::steady_clock::now();
			double remaining = ::std::chrono::duration<double>(this->getDuration()).count();
			this->iteration = 0;

			::rl::math::Vector rand(this->kinematic->getDof());
			::rl::math::Vector q = this->kinematic->getPosition();
			double optF;

			do
			{
				if (::nlopt_set_maxeval(opt.get(), this->getIterations() - this->iteration) < 0)
				{
					return false;
				}

				if (::nlopt_set_maxtime(opt.get(), remaining) < 0)
				{
					return false;
				}

				::nlopt_result result = ::nlopt_optimize(opt.get(), q.data(), &optF);

				if (::NLOPT_STOPVAL_REACHED == result)
				{
					return true;
				}
				else if (result < -1)
				{
					return false;
				}

				for (::std::size_t i = 0; i < this->kinematic->getDof(); ++i)
				{
					rand(i) = this->randDistribution(this->randEngine);
				}

				q = this->kinematic->generatePositionUniform(rand, this->lb, this->ub);

				remaining = ::std::chrono::duration<double>(this->getDuration() - (::std::chrono::steady_clock::now() - start)).count();
			}
			while (remaining > 0 && this->iteration < this->getIterations());

			return false;
		}

		NloptInverseKinematics::Exception::Exception(const ::nlopt_result& result) :
			::rl::mdl::Exception(::std::string()),
			result(result)
		{
		}

		NloptInverseKinematics::Exception::~Exception() throw()
		{
		}

		void
		NloptInverseKinematics::Exception::check(const ::nlopt_result& result)
		{
			if (result < 0)
			{
				throw Exception(result);
			}
		}

		::nlopt_result
		NloptInverseKinematics::Exception::getResult() const
		{
			return this->result;
		}

		const char*
		NloptInverseKinematics::Exception::what() const throw()
		{
			switch (this->result)
			{
			case ::NLOPT_FAILURE:
				return "Generic failure.";
				break;
			case ::NLOPT_INVALID_ARGS:
				return "Invalid arguments.";
				break;
			case ::NLOPT_OUT_OF_MEMORY:
				return "Out of memory.";
				break;
			case ::NLOPT_ROUNDOFF_LIMITED:
				return "Halted because roundoff errors limited progress.";
				break;
			case ::NLOPT_FORCED_STOP:
				return "Halted because of a forced termination.";
				break;
			default:
				return "Unknown error.";
				break;
			}
		}
	}
}
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

// StochasticTools includes
#include "SamplerFullSolveMultiApp.h"
#include "Sampler.h"
#include "StochasticToolsTransfer.h"

registerMooseObject("StochasticToolsApp", SamplerFullSolveMultiApp);

InputParameters
SamplerFullSolveMultiApp::validParams()
{
  InputParameters params = FullSolveMultiApp::validParams();
  params += SamplerInterface::validParams();
  params.addClassDescription(
      "Creates a full-solve type sub-application for each row of each Sampler matrix.");
  params.addParam<SamplerName>("sampler", "The Sampler object to utilize for creating MultiApps.");
  params.suppressParameter<std::vector<Point>>("positions");
  params.suppressParameter<bool>("output_in_position");
  params.suppressParameter<std::vector<FileName>>("positions_file");
  params.suppressParameter<Real>("move_time");
  params.suppressParameter<std::vector<Point>>("move_positions");
  params.suppressParameter<std::vector<unsigned int>>("move_apps");
  params.set<bool>("use_positions") = false;

  MooseEnum modes("normal=0 batch-reset=1 batch-restore=2", "normal");
  params.addParam<MooseEnum>(
      "mode",
      modes,
      "The operation mode, 'normal' creates one sub-application for each row in the Sampler and "
      "'batch' creates one sub-application for each processor and re-executes for each row.");
  return params;
}

SamplerFullSolveMultiApp::SamplerFullSolveMultiApp(const InputParameters & parameters)
  : FullSolveMultiApp(parameters),
    SamplerInterface(this),
    _sampler(SamplerInterface::getSampler("sampler")),
    _mode(getParam<MooseEnum>("mode").getEnum<StochasticTools::MultiAppMode>()),
    _local_batch_app_index(0),
    _solved_once(false),
    _perf_solve_step(registerTimedSection("solveStep", 1)),
    _perf_solve_batch_step(registerTimedSection("solveStepBatch", 1)),
    _perf_command_line_args(registerTimedSection("getCommandLineArgsParamHelper", 4))
{
  if (_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
      _mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
  {
    if (n_processors() > _sampler.getNumberOfRows())
      paramError(
          "mode",
          "There appears to be more available processors (",
          n_processors(),
          ") than samples (",
          _sampler.getNumberOfRows(),
          "), this is not supported in "
          "batch mode. Consider switching to \'normal\' to allow multiple processors per sample.");
    init(n_processors());
  }
  else
    init(_sampler.getNumberOfRows());

  _number_of_sampler_rows = _sampler.getNumberOfRows();
}

void SamplerFullSolveMultiApp::preTransfer(Real /*dt*/, Real /*target_time*/)
{
  if (_mode == StochasticTools::MultiAppMode::NORMAL)
  {
    // Reinitialize MultiApp size
    const auto num_rows = _sampler.getNumberOfRows();
    if (num_rows != _number_of_sampler_rows)
    {
      init(_sampler.getNumberOfRows());
      _number_of_sampler_rows = num_rows;
    }

    // Reinitialize app to original state prior to solve, if a solve has occured
    if (_solved_once)
      initialSetup();
  }
}

bool
SamplerFullSolveMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)
{
  TIME_SECTION(_perf_solve_step);

  mooseAssert(_my_num_apps, _sampler.getNumberOfLocalRows());

  bool last_solve_converged = true;

  if (_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
      _mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
    last_solve_converged = solveStepBatch(dt, target_time, auto_advance);
  else
    last_solve_converged = FullSolveMultiApp::solveStep(dt, target_time, auto_advance);

  _solved_once = true;

  return last_solve_converged;
}

bool
SamplerFullSolveMultiApp::solveStepBatch(Real dt, Real target_time, bool auto_advance)
{
  TIME_SECTION(_perf_solve_batch_step);

  // Value to return
  bool last_solve_converged = true;

  // Reinitialize app to original state prior to solve, if a solve has occured
  if (_solved_once)
    initialSetup();

  // List of active relevant Transfer objects
  std::vector<std::shared_ptr<StochasticToolsTransfer>> to_transfers =
      getActiveStochasticToolsTransfers(MultiAppTransfer::TO_MULTIAPP);
  std::vector<std::shared_ptr<StochasticToolsTransfer>> from_transfers =
      getActiveStochasticToolsTransfers(MultiAppTransfer::FROM_MULTIAPP);

  // Initialize to/from transfers
  for (auto transfer : to_transfers)
    transfer->initializeToMultiapp();

  for (auto transfer : from_transfers)
    transfer->initializeFromMultiapp();

  if (_mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
    backup();

  // Perform batch MultiApp solves
  _local_batch_app_index = 0;
  for (dof_id_type i = _sampler.getLocalRowBegin(); i < _sampler.getLocalRowEnd(); ++i)
  {
    for (auto & transfer : to_transfers)
    {
      transfer->setGlobalMultiAppIndex(i);
      transfer->executeToMultiapp();
    }

    last_solve_converged = FullSolveMultiApp::solveStep(dt, target_time, auto_advance);

    for (auto & transfer : from_transfers)
    {
      transfer->setGlobalMultiAppIndex(i);
      transfer->executeFromMultiapp();
    }

    if (i < _sampler.getLocalRowEnd() - 1)
    {
      if (_mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
        restore();
      else
      {
        // The app is being reset for the next loop, thus the batch index must be indexed as such
        _local_batch_app_index = i + 1;
        resetApp(_local_batch_app_index, target_time);
        initialSetup();
      }
    }
  }

  // Finalize to/from transfers
  for (auto transfer : to_transfers)
    transfer->finalizeToMultiapp();
  for (auto transfer : from_transfers)
    transfer->finalizeFromMultiapp();

  return last_solve_converged;
}

std::vector<std::shared_ptr<StochasticToolsTransfer>>
SamplerFullSolveMultiApp::getActiveStochasticToolsTransfers(Transfer::DIRECTION direction)
{
  std::vector<std::shared_ptr<StochasticToolsTransfer>> output;
  const ExecuteMooseObjectWarehouse<Transfer> & warehouse =
      _fe_problem.getMultiAppTransferWarehouse(direction);
  for (std::shared_ptr<Transfer> transfer : warehouse.getActiveObjects())
  {
    auto ptr = std::dynamic_pointer_cast<StochasticToolsTransfer>(transfer);
    if (ptr && ptr->getMultiApp()->name() == this->name())
      output.push_back(ptr);
  }
  return output;
}

std::string
SamplerFullSolveMultiApp::getCommandLineArgsParamHelper(unsigned int local_app)
{
  TIME_SECTION(_perf_command_line_args);

  // Since we only store param_names in cli_args, we need to find the values for each param from
  // sampler data and combine them to get full command line option strings.
  std::vector<Real> row = _sampler.getNextLocalRow();

  std::ostringstream oss;
  const std::vector<std::string> & cli_args_name =
      MooseUtils::split(FullSolveMultiApp::getCommandLineArgsParamHelper(local_app), ";");

  for (dof_id_type col = 0; col < _sampler.getNumberOfCols(); ++col)
  {
    if (col > 0)
      oss << ";";
    oss << cli_args_name[col] << "=" << Moose::stringify(row[col]);
  }
  return oss.str();
}
<commit_msg>Update modules/stochastic_tools/src/multiapps/SamplerFullSolveMultiApp.C<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

// StochasticTools includes
#include "SamplerFullSolveMultiApp.h"
#include "Sampler.h"
#include "StochasticToolsTransfer.h"

registerMooseObject("StochasticToolsApp", SamplerFullSolveMultiApp);

InputParameters
SamplerFullSolveMultiApp::validParams()
{
  InputParameters params = FullSolveMultiApp::validParams();
  params += SamplerInterface::validParams();
  params.addClassDescription(
      "Creates a full-solve type sub-application for each row of each Sampler matrix.");
  params.addParam<SamplerName>("sampler", "The Sampler object to utilize for creating MultiApps.");
  params.suppressParameter<std::vector<Point>>("positions");
  params.suppressParameter<bool>("output_in_position");
  params.suppressParameter<std::vector<FileName>>("positions_file");
  params.suppressParameter<Real>("move_time");
  params.suppressParameter<std::vector<Point>>("move_positions");
  params.suppressParameter<std::vector<unsigned int>>("move_apps");
  params.set<bool>("use_positions") = false;

  MooseEnum modes("normal=0 batch-reset=1 batch-restore=2", "normal");
  params.addParam<MooseEnum>(
      "mode",
      modes,
      "The operation mode, 'normal' creates one sub-application for each row in the Sampler and "
      "'batch' creates one sub-application for each processor and re-executes for each row.");
  return params;
}

SamplerFullSolveMultiApp::SamplerFullSolveMultiApp(const InputParameters & parameters)
  : FullSolveMultiApp(parameters),
    SamplerInterface(this),
    _sampler(SamplerInterface::getSampler("sampler")),
    _mode(getParam<MooseEnum>("mode").getEnum<StochasticTools::MultiAppMode>()),
    _local_batch_app_index(0),
    _solved_once(false),
    _perf_solve_step(registerTimedSection("solveStep", 1)),
    _perf_solve_batch_step(registerTimedSection("solveStepBatch", 1)),
    _perf_command_line_args(registerTimedSection("getCommandLineArgsParamHelper", 4))
{
  if (_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
      _mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
  {
    if (n_processors() > _sampler.getNumberOfRows())
      paramError(
          "mode",
          "There appears to be more available processors (",
          n_processors(),
          ") than samples (",
          _sampler.getNumberOfRows(),
          "), this is not supported in "
          "batch mode. Consider switching to \'normal\' to allow multiple processors per sample.");
    init(n_processors());
  }
  else
    init(_sampler.getNumberOfRows());

  _number_of_sampler_rows = _sampler.getNumberOfRows();
}

void SamplerFullSolveMultiApp::preTransfer(Real /*dt*/, Real /*target_time*/)
{
  if (_mode == StochasticTools::MultiAppMode::NORMAL)
  {
    // Reinitialize MultiApp size
    const auto num_rows = _sampler.getNumberOfRows();
    if (num_rows != _number_of_sampler_rows)
    {
      init(_sampler.getNumberOfRows());
      _number_of_sampler_rows = num_rows;
    }

    // Reinitialize app to original state prior to solve, if a solve has occured
    if (_solved_once)
      initialSetup();
  }
}

bool
SamplerFullSolveMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)
{
  TIME_SECTION(_perf_solve_step);

  mooseAssert(_my_num_apps, _sampler.getNumberOfLocalRows());

  bool last_solve_converged = true;

  if (_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
      _mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
    last_solve_converged = solveStepBatch(dt, target_time, auto_advance);
  else
    last_solve_converged = FullSolveMultiApp::solveStep(dt, target_time, auto_advance);

  _solved_once = true;

  return last_solve_converged;
}

bool
SamplerFullSolveMultiApp::solveStepBatch(Real dt, Real target_time, bool auto_advance)
{
  TIME_SECTION(_perf_solve_batch_step);

  // Value to return
  bool last_solve_converged = true;

  // Reinitialize app to original state prior to solve, if a solve has occured
  if (_solved_once)
    initialSetup();

  // List of active relevant Transfer objects
  std::vector<std::shared_ptr<StochasticToolsTransfer>> to_transfers =
      getActiveStochasticToolsTransfers(MultiAppTransfer::TO_MULTIAPP);
  std::vector<std::shared_ptr<StochasticToolsTransfer>> from_transfers =
      getActiveStochasticToolsTransfers(MultiAppTransfer::FROM_MULTIAPP);

  // Initialize to/from transfers
  for (auto transfer : to_transfers)
    transfer->initializeToMultiapp();

  for (auto transfer : from_transfers)
    transfer->initializeFromMultiapp();

  if (_mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
    backup();

  // Perform batch MultiApp solves
  _local_batch_app_index = 0;
  for (dof_id_type i = _sampler.getLocalRowBegin(); i < _sampler.getLocalRowEnd(); ++i)
  {
    for (auto & transfer : to_transfers)
    {
      transfer->setGlobalMultiAppIndex(i);
      transfer->executeToMultiapp();
    }

    last_solve_converged = FullSolveMultiApp::solveStep(dt, target_time, auto_advance);

    for (auto & transfer : from_transfers)
    {
      transfer->setGlobalMultiAppIndex(i);
      transfer->executeFromMultiapp();
    }

    if (i < _sampler.getLocalRowEnd() - 1)
    {
      if (_mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
        restore();
      else
      {
        // The app is being reset for the next loop, thus the batch index must be indexed as such
        _local_batch_app_index = i + 1;
        resetApp(_local_batch_app_index, target_time);
        initialSetup();
      }
    }
  }

  // Finalize to/from transfers
  for (auto transfer : to_transfers)
    transfer->finalizeToMultiapp();
  for (auto transfer : from_transfers)
    transfer->finalizeFromMultiapp();

  return last_solve_converged;
}

std::vector<std::shared_ptr<StochasticToolsTransfer>>
SamplerFullSolveMultiApp::getActiveStochasticToolsTransfers(Transfer::DIRECTION direction)
{
  std::vector<std::shared_ptr<StochasticToolsTransfer>> output;
  const ExecuteMooseObjectWarehouse<Transfer> & warehouse =
      _fe_problem.getMultiAppTransferWarehouse(direction);
  for (std::shared_ptr<Transfer> transfer : warehouse.getActiveObjects())
  {
    auto ptr = std::dynamic_pointer_cast<StochasticToolsTransfer>(transfer);
    if (ptr && ptr->getMultiApp().get() == this)
      output.push_back(ptr);
  }
  return output;
}

std::string
SamplerFullSolveMultiApp::getCommandLineArgsParamHelper(unsigned int local_app)
{
  TIME_SECTION(_perf_command_line_args);

  // Since we only store param_names in cli_args, we need to find the values for each param from
  // sampler data and combine them to get full command line option strings.
  std::vector<Real> row = _sampler.getNextLocalRow();

  std::ostringstream oss;
  const std::vector<std::string> & cli_args_name =
      MooseUtils::split(FullSolveMultiApp::getCommandLineArgsParamHelper(local_app), ";");

  for (dof_id_type col = 0; col < _sampler.getNumberOfCols(); ++col)
  {
    if (col > 0)
      oss << ";";
    oss << cli_args_name[col] << "=" << Moose::stringify(row[col]);
  }
  return oss.str();
}
<|endoftext|>


<commit_before>#include <plasp/pddl/InitialState.h>

#include <plasp/pddl/Context.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/expressions/Predicate.h>
#include <plasp/utils/ParserException.h>

namespace plasp
{
namespace pddl
{

////////////////////////////////////////////////////////////////////////////////////////////////////
//
// InitialState
//
////////////////////////////////////////////////////////////////////////////////////////////////////

inline void warnUnsupported(Context &context, const std::string &expressionIdentifier)
{
	context.logger.parserWarning(context.parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
	skipSection(context.parser);
}

////////////////////////////////////////////////////////////////////////////////////////////////////

std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context, const Problem &problem)
{
	auto &parser = context.parser;

	auto initialState = std::make_unique<InitialState>(InitialState());

	const auto parseInitialStateElement =
		[&]()
		{
			ExpressionPointer expression;

			if ((expression = expressions::Predicate::parse(context, problem)))
				return expression;

			const auto position = parser.position();

			parser.expect<std::string>("(");

			const auto expressionIdentifierPosition = parser.position();

			if (parser.probeIdentifier("at")
				|| parser.probeIdentifier("=")
				|| parser.probeIdentifier("not"))
			{
				parser.seek(expressionIdentifierPosition);
				const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);

				parser.seek(position);
				warnUnsupported(context, expressionIdentifier);

				return ExpressionPointer();
			}

			parser.seek(expressionIdentifierPosition);
			const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);

			parser.seek(position);
			throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
		};

	parser.skipWhiteSpace();

	while (parser.currentCharacter() != ')')
	{
		ExpressionPointer expression;

		if ((expression = parseInitialStateElement()))
			initialState->m_facts.emplace_back(std::move(expression));

		parser.skipWhiteSpace();
	}

	return initialState;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

}
}
<commit_msg>Added missing implementation of facts accessor of InitialState.<commit_after>#include <plasp/pddl/InitialState.h>

#include <plasp/pddl/Context.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/expressions/Predicate.h>
#include <plasp/utils/ParserException.h>

namespace plasp
{
namespace pddl
{

////////////////////////////////////////////////////////////////////////////////////////////////////
//
// InitialState
//
////////////////////////////////////////////////////////////////////////////////////////////////////

inline void warnUnsupported(Context &context, const std::string &expressionIdentifier)
{
	context.logger.parserWarning(context.parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
	skipSection(context.parser);
}

////////////////////////////////////////////////////////////////////////////////////////////////////

std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context, const Problem &problem)
{
	auto &parser = context.parser;

	auto initialState = std::make_unique<InitialState>(InitialState());

	const auto parseInitialStateElement =
		[&]()
		{
			ExpressionPointer expression;

			if ((expression = expressions::Predicate::parse(context, problem)))
				return expression;

			const auto position = parser.position();

			parser.expect<std::string>("(");

			const auto expressionIdentifierPosition = parser.position();

			if (parser.probeIdentifier("at")
				|| parser.probeIdentifier("=")
				|| parser.probeIdentifier("not"))
			{
				parser.seek(expressionIdentifierPosition);
				const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);

				parser.seek(position);
				warnUnsupported(context, expressionIdentifier);

				return ExpressionPointer();
			}

			parser.seek(expressionIdentifierPosition);
			const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);

			parser.seek(position);
			throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
		};

	parser.skipWhiteSpace();

	while (parser.currentCharacter() != ')')
	{
		ExpressionPointer expression;

		if ((expression = parseInitialStateElement()))
			initialState->m_facts.emplace_back(std::move(expression));

		parser.skipWhiteSpace();
	}

	return initialState;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

const Expressions &InitialState::facts() const
{
	return m_facts;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014-2020 AscEmu Team <http://www.ascemu.org>
 * Copyright (c) 2008-2019 Sun++ Team <http://www.sunplusplus.info/>
 * Copyright (C) 2008-2012 ArcEmu Team <http://www.ArcEmu.org/>
 * Copyright (C) 2008 WEmu Team
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * 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 General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "Setup.h"

// QUEST_CLUCK         3861
// ITEM_CHICKEN_FEED   11109

class Quest_Grimoire_Business : public QuestScript
{
public:

    void OnQuestStart(Player* mTarget, QuestLogEntry* /*qLogEntry*/) override
    {
        Creature* ct = mTarget->GetMapMgr()->CreateAndSpawnCreature(22911, 3279.67f, 4640.77f, 216.526f, 1.3516f);
        if (ct != nullptr)
            ct->Despawn(2 * 60 * 1000, 0);
    }
};

class Quest_Maggocs_Treasure_Chest : public QuestScript
{
public:

    void OnQuestStart(Player* mTarget, QuestLogEntry* /*qLogEntry*/) override
    {
        mTarget->GetMapMgr()->GetInterface()->SpawnCreature(20600, 2001.76f, 5164.77f, 265.19f, 5.5148f, true, false, 0, 0);
    }
};

class Quest_Grulloc_Has_Two_Skulls : public QuestScript
{
public:

    void OnQuestStart(Player* mTarget, QuestLogEntry* /*qLogEntry*/) override
    {
        Creature* ct = mTarget->GetMapMgr()->CreateAndSpawnCreature(20216, 2687.46f, 5541.14f, -1.93669f, 3.52847f);
        if (ct != nullptr)
            ct->Despawn(2 * 60 * 1000, 0);
    }
};

class Quest_Zuluhed_the_Whacked : public QuestScript
{
public:

    void OnQuestStart(Player* mTarget, QuestLogEntry* /*qLogEntry*/) override
    {
        Creature* ct = mTarget->GetMapMgr()->CreateAndSpawnCreature(11980, -4177.39f, 376.289f, 117.78f, 2.7381f);
        if (ct != nullptr)
            ct->Despawn(2 * 60 * 1000, 0);
    }
};

class Chicken : public CreatureAIScript
{
    ADD_CREATURE_FACTORY_FUNCTION(Chicken)
    explicit Chicken(Creature* pCreature) : CreatureAIScript(pCreature) {}

    void OnLoad() override
    {
        getCreature()->SetFaction(12);
        getCreature()->removeNpcFlags(UNIT_NPC_FLAG_QUESTGIVER);
        RegisterAIUpdateEvent(120000);
    }

    void AIUpdate() override
    {
        if(getCreature()->getNpcFlags() & UNIT_NPC_FLAG_QUESTGIVER)
            OnLoad();
    }
};

class Kaliri : public CreatureAIScript
{
    ADD_CREATURE_FACTORY_FUNCTION(Kaliri)
    explicit Kaliri(Creature* pCreature) : CreatureAIScript(pCreature) {}

    void OnLoad() override
    {
        getCreature()->SetFaction(35);
    }
};

void SetupUnsorted(ScriptMgr* mgr)
{
    mgr->register_quest_script(10998, new Quest_Grimoire_Business());
    mgr->register_quest_script(10996, new Quest_Maggocs_Treasure_Chest());
    mgr->register_quest_script(10995, new Quest_Grulloc_Has_Two_Skulls());
    mgr->register_quest_script(10866, new Quest_Zuluhed_the_Whacked());
    mgr->register_creature_script(620, &Chicken::Create);
    mgr->register_creature_script(21468, &Kaliri::Create);
}
<commit_msg>fix npc id 620 chicken (disabled script)<commit_after>/*
 * Copyright (c) 2014-2020 AscEmu Team <http://www.ascemu.org>
 * Copyright (c) 2008-2019 Sun++ Team <http://www.sunplusplus.info/>
 * Copyright (C) 2008-2012 ArcEmu Team <http://www.ArcEmu.org/>
 * Copyright (C) 2008 WEmu Team
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * 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 General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "Setup.h"

// QUEST_CLUCK         3861
// ITEM_CHICKEN_FEED   11109

class Quest_Grimoire_Business : public QuestScript
{
public:
    void OnQuestStart(Player* mTarget, QuestLogEntry* /*qLogEntry*/) override
    {
        Creature* ct = mTarget->GetMapMgr()->CreateAndSpawnCreature(22911, 3279.67f, 4640.77f, 216.526f, 1.3516f);
        if (ct != nullptr)
            ct->Despawn(2 * 60 * 1000, 0);
    }
};

class Quest_Maggocs_Treasure_Chest : public QuestScript
{
public:
    void OnQuestStart(Player* mTarget, QuestLogEntry* /*qLogEntry*/) override
    {
        mTarget->GetMapMgr()->GetInterface()->SpawnCreature(20600, 2001.76f, 5164.77f, 265.19f, 5.5148f, true, false, 0, 0);
    }
};

class Quest_Grulloc_Has_Two_Skulls : public QuestScript
{
public:
    void OnQuestStart(Player* mTarget, QuestLogEntry* /*qLogEntry*/) override
    {
        Creature* ct = mTarget->GetMapMgr()->CreateAndSpawnCreature(20216, 2687.46f, 5541.14f, -1.93669f, 3.52847f);
        if (ct != nullptr)
            ct->Despawn(2 * 60 * 1000, 0);
    }
};

class Quest_Zuluhed_the_Whacked : public QuestScript
{
public:
    void OnQuestStart(Player* mTarget, QuestLogEntry* /*qLogEntry*/) override
    {
        Creature* ct = mTarget->GetMapMgr()->CreateAndSpawnCreature(11980, -4177.39f, 376.289f, 117.78f, 2.7381f);
        if (ct != nullptr)
            ct->Despawn(2 * 60 * 1000, 0);
    }
};

/* class Chicken : public CreatureAIScript
{
    ADD_CREATURE_FACTORY_FUNCTION(Chicken)
    explicit Chicken(Creature* pCreature) : CreatureAIScript(pCreature) {}

    void OnLoad() override
    {
        getCreature()->SetFaction(12);
        getCreature()->removeNpcFlags(UNIT_NPC_FLAG_QUESTGIVER);
        RegisterAIUpdateEvent(120000);
    }

    void AIUpdate() override
    {
        if(getCreature()->getNpcFlags() & UNIT_NPC_FLAG_QUESTGIVER)
            OnLoad();
    }
}; */

class Kaliri : public CreatureAIScript
{
    ADD_CREATURE_FACTORY_FUNCTION(Kaliri)
    explicit Kaliri(Creature* pCreature) : CreatureAIScript(pCreature) {}

    void OnLoad() override
    {
        getCreature()->SetFaction(35);
    }
};

void SetupUnsorted(ScriptMgr* mgr)
{
    mgr->register_quest_script(10998, new Quest_Grimoire_Business());
    mgr->register_quest_script(10996, new Quest_Maggocs_Treasure_Chest());
    mgr->register_quest_script(10995, new Quest_Grulloc_Has_Two_Skulls());
    mgr->register_quest_script(10866, new Quest_Zuluhed_the_Whacked());
    //mgr->register_creature_script(620, &Chicken::Create);
    mgr->register_creature_script(21468, &Kaliri::Create);
}
<|endoftext|>


<commit_before><commit_msg>Delete file.<commit_after><|endoftext|>


<commit_before>#include "set.h"
#include <limits>
#include <algorithm>
#include <sstream>
#include <iostream>

Deg::Runtime::Math::Set::Conjunction::Conjunction() {
	return;
}

Deg::Runtime::Math::Set::Conjunction::Conjunction(unsigned int Field, int BottomEq, int TopNeq) {
	Clauses[Field] = Interval<int>(BottomEq, TopNeq);
	return;
}

bool Deg::Runtime::Math::Set::Conjunction::IsEmpty() const {
	for(const auto& em : Clauses) {
		if(em.second.IsEmpty()) {
			return true;
		}
	}

	return false;
}

bool Deg::Runtime::Math::Set::Conjunction::IsSubsetOf(const Conjunction& c) const {
	for(const auto& em : Clauses) {
		auto it = c.Clauses.find(em.first);
		if(it != c.Clauses.end()) {
			if(!it->second.Contains(em.second)) {
				return false;
			}
		}
	}

	return true;
}

void Deg::Runtime::Math::Set::DisjoinOne(const Conjunction& base, const Conjunction& minus, std::vector<Conjunction>& output) {
	Conjunction middle_conj = base;

	for(const auto& rng : minus.Clauses) {
		Interval<int> left, middle, right;

		auto it = middle_conj.Clauses.find(rng.first);
		if(it == middle_conj.Clauses.end()) {
			// Full coverage.
			left = Interval<int>(std::numeric_limits<int>::lowest(), rng.second.bottom);
			middle = Interval<int>(rng.second);
			right = Interval<int>(rng.second.top, std::numeric_limits<int>::max());
		}
		else if(Interval<int>::Disjoint(it->second, rng.second)) {
			output.push_back(middle_conj);
			return;
		}
		else {
			left = Interval<int>(it->second.bottom, rng.second.bottom);
			middle = Interval<int>(std::max(it->second.bottom, rng.second.bottom), std::min(it->second.top, rng.second.top));
			right = Interval<int>(rng.second.top, it->second.top);
		}

		if(!left.IsEmpty()) {
			Conjunction left_conj(middle_conj);
			left_conj.Clauses[rng.first] = left;
			output.push_back(left_conj);
		}

		if(!right.IsEmpty()) {
			Conjunction right_conj(middle_conj);
			right_conj.Clauses[rng.first] = right;
			output.push_back(right_conj);
		}

		middle_conj.Clauses[rng.first] = middle;
	}
}

void Deg::Runtime::Math::Set::Disjoin() {
	if(Disjunction.empty()) {
		return;
	}

	std::vector<Conjunction> output;
	std::vector<Conjunction> current = { Disjunction.front() };

	for(auto it = Disjunction.begin() + 1; it != Disjunction.end(); ++it) {
		output.clear();

		for(auto& one : current) {
			DisjoinOne(one, *it, output);
		}

		output.push_back(*it);

		std::swap(output, current);
	}

	std::swap(current, Disjunction);
}

bool Deg::Runtime::Math::Set::CanMerge(const Conjunction& a, const Conjunction& b) {
	bool union_once = false;
	for(const auto& rng : a.Clauses) {
		auto it = b.Clauses.find(rng.first);
		if(it != b.Clauses.end()) {
			if(rng.second == it->second) {
				continue;
			}
			else if(union_once) {
				return false;
			}
			else if(Interval<int>::CanUnion(rng.second, it->second)) {
				union_once = true;
			}
			else {
				return false;
			}
		}
	}

	return true;
}

void Deg::Runtime::Math::Set::MergeOne(Conjunction& target, const Conjunction& c) {
	for(auto& rng : target.Clauses) {
		auto it = c.Clauses.find(rng.first);
		if(it != c.Clauses.end()) {
			rng.second = Interval<int>::Union(rng.second, it->second);
		}
		else {
			rng.second = Interval<int>(std::numeric_limits<int>::lowest(), std::numeric_limits<int>::max());
		}
	}
}

bool Deg::Runtime::Math::Set::TryMerge() {
	for(size_t i = 0; i < Disjunction.size(); ++i) {
		for(size_t j = i + 1; j < Disjunction.size();) {
			if(CanMerge(Disjunction[i], Disjunction[j])) {
				MergeOne(Disjunction[i], Disjunction[j]);
				if(Disjunction.size() - 1 > j) {
					Disjunction[j] = Disjunction[Disjunction.size() - 1];
				}

				Disjunction.pop_back();
				return true;
			}
			else {
				++j;
			}
		}
	}

	return false;
}

void Deg::Runtime::Math::Set::Merge() {
	while(TryMerge());
}

void Deg::Runtime::Math::Set::ReduceOne(Conjunction& target) {
	for(auto it = target.Clauses.begin(); it != target.Clauses.end();) {
		if(it->second.bottom == std::numeric_limits<int>::lowest() && it->second.top == std::numeric_limits<int>::max()) {
			it = target.Clauses.erase(it);
		}
		else {
			++it;
		}
	}
}

void Deg::Runtime::Math::Set::Reduce() {
	Disjoin();
	Merge();

	for(auto& conj : Disjunction) {
		ReduceOne(conj);
	}

	auto it = std::remove_if(Disjunction.begin(), Disjunction.end(),
			[](const Conjunction& val) { return val.IsEmpty(); });
	Disjunction.erase(it, Disjunction.end());

	return;
}

Deg::Runtime::Math::Set::Set() {
	return;
}

Deg::Runtime::Math::Set::Set(unsigned int field, Relation relation, int value) {
	switch(relation) {
	case Relation::Less:
		Disjunction.push_back(Conjunction(field, std::numeric_limits<int>::lowest(), value));
		break;

	case Relation::LessEqual:
		Disjunction.push_back(Conjunction(field, std::numeric_limits<int>::lowest(), value + 1));
		break;

	case Relation::Greater:
		Disjunction.push_back(Conjunction(field, value + 1, std::numeric_limits<int>::max()));
		break;

	case Relation::GreaterEqual:
		Disjunction.push_back(Conjunction(field, value, std::numeric_limits<int>::max()));
		break;

	case Relation::Equal:
		Disjunction.push_back(Conjunction(field, value, value + 1));
		break;

	case Relation::NotEqual:
		Disjunction.push_back(Conjunction(field, std::numeric_limits<int>::lowest(), value));
		Disjunction.push_back(Conjunction(field, value + 1, std::numeric_limits<int>::max()));
		break;
	}
}

bool Deg::Runtime::Math::Set::IsEmpty() const {
	for(const auto& em : Disjunction) {
		if(!em.IsEmpty()) {
			return false;
		}
	}

	return true;
}

bool Deg::Runtime::Math::Set::IsSubsetOf(const Set& s) const {
	for(const auto& em : Disjunction) {
		// Each conjunction must be the subset of a conjunction in s.
		bool is_subset = false;

		for(const auto& en : s.Disjunction) {
			if(em.IsSubsetOf(en)) {
				is_subset = true;
				break;
			}
		}

		if(!is_subset) {
			return false;
		}
	}

	return true;
}

bool Deg::Runtime::Math::Set::operator==(const Set& s) const {
	return IsSubsetOf(s) && s.IsSubsetOf(*this);
}

bool Deg::Runtime::Math::Set::operator!=(const Set& s) const {
	return !(*this == s);
}

Deg::Runtime::Math::Set Deg::Runtime::Math::Set::operator&(const Set& s) const {
	// Intersection
	Set rv;
	for(const auto& cj : Disjunction) {
		for(const auto& scj : s.Disjunction) {
			Conjunction c = cj;
			for(const auto& sclause : scj.Clauses) {
				auto it = c.Clauses.find(sclause.first);
				if(it == c.Clauses.end()) {
					// No such clause
					c.Clauses[sclause.first] = sclause.second;
				}
				else {
					it->second = Interval<int>::Intersect(it->second, sclause.second);
				}
			}

			rv.Disjunction.push_back(c);
		}
	}

	rv.Reduce();
	return rv;
}

Deg::Runtime::Math::Set Deg::Runtime::Math::Set::operator|(const Set& s) const {
	Set rv;
	rv.Disjunction.insert(rv.Disjunction.end(), Disjunction.begin(), Disjunction.end());
	rv.Disjunction.insert(rv.Disjunction.end(), s.Disjunction.begin(), s.Disjunction.end());
	rv.Reduce();
	return rv;
}

Deg::Runtime::Math::Set Deg::Runtime::Math::Set::operator-(const Set& s) const {
	if(s.IsEmpty()) {
		return *this;
	}

	Set rv;

	std::vector<Conjunction> output;
	std::vector<Conjunction> current = Disjunction;

	for(const auto& dis : s.Disjunction) {
		output.clear();

		for(const auto& one : current) {
			DisjoinOne(one, dis, output);
		}

		std::swap(output, current);
	}

	std::swap(rv.Disjunction, current);
	rv.Reduce();
	return rv;
}

std::ostream& Deg::Runtime::Math::operator<<(std::ostream& os, const Set& s) {
	std::stringstream ss;
	ss << "{";

	bool p_dis_or = false;
	for(const auto& dis : s.Disjunction) {
		if(p_dis_or) {
			ss << "v";
		}
		else {
			p_dis_or = true;
		}

		ss << "(";

		bool p_con_and = false;
		for(const auto& con : dis.Clauses) {
			if(p_con_and) {
				ss << "^";
			}
			else {
				p_con_and = true;
			}

			ss << con.first << ":[" << con.second.bottom << "," << con.second.top << "]";
		}

		ss << ")";
	}

	ss << "}";
	return os << ss.str();
}
<commit_msg>Replaced some push_backs with emplace_backs in set.<commit_after>#include "set.h"
#include <limits>
#include <algorithm>
#include <sstream>
#include <iostream>

Deg::Runtime::Math::Set::Conjunction::Conjunction() {
	return;
}

Deg::Runtime::Math::Set::Conjunction::Conjunction(unsigned int Field, int BottomEq, int TopNeq) {
	Clauses[Field] = Interval<int>(BottomEq, TopNeq);
	return;
}

bool Deg::Runtime::Math::Set::Conjunction::IsEmpty() const {
	for(const auto& em : Clauses) {
		if(em.second.IsEmpty()) {
			return true;
		}
	}

	return false;
}

bool Deg::Runtime::Math::Set::Conjunction::IsSubsetOf(const Conjunction& c) const {
	for(const auto& em : Clauses) {
		auto it = c.Clauses.find(em.first);
		if(it != c.Clauses.end()) {
			if(!it->second.Contains(em.second)) {
				return false;
			}
		}
	}

	return true;
}

void Deg::Runtime::Math::Set::DisjoinOne(const Conjunction& base, const Conjunction& minus, std::vector<Conjunction>& output) {
	Conjunction middle_conj = base;

	for(const auto& rng : minus.Clauses) {
		Interval<int> left, middle, right;

		auto it = middle_conj.Clauses.find(rng.first);
		if(it == middle_conj.Clauses.end()) {
			// Full coverage.
			left = Interval<int>(std::numeric_limits<int>::lowest(), rng.second.bottom);
			middle = Interval<int>(rng.second);
			right = Interval<int>(rng.second.top, std::numeric_limits<int>::max());
		}
		else if(Interval<int>::Disjoint(it->second, rng.second)) {
			output.push_back(middle_conj);
			return;
		}
		else {
			left = Interval<int>(it->second.bottom, rng.second.bottom);
			middle = Interval<int>(std::max(it->second.bottom, rng.second.bottom), std::min(it->second.top, rng.second.top));
			right = Interval<int>(rng.second.top, it->second.top);
		}

		if(!left.IsEmpty()) {
			Conjunction left_conj(middle_conj);
			left_conj.Clauses[rng.first] = left;
			output.push_back(left_conj);
		}

		if(!right.IsEmpty()) {
			Conjunction right_conj(middle_conj);
			right_conj.Clauses[rng.first] = right;
			output.push_back(right_conj);
		}

		middle_conj.Clauses[rng.first] = middle;
	}
}

void Deg::Runtime::Math::Set::Disjoin() {
	if(Disjunction.empty()) {
		return;
	}

	std::vector<Conjunction> output;
	std::vector<Conjunction> current = { Disjunction.front() };

	for(auto it = Disjunction.begin() + 1; it != Disjunction.end(); ++it) {
		output.clear();

		for(auto& one : current) {
			DisjoinOne(one, *it, output);
		}

		output.push_back(*it);

		std::swap(output, current);
	}

	std::swap(current, Disjunction);
}

bool Deg::Runtime::Math::Set::CanMerge(const Conjunction& a, const Conjunction& b) {
	bool union_once = false;
	for(const auto& rng : a.Clauses) {
		auto it = b.Clauses.find(rng.first);
		if(it != b.Clauses.end()) {
			if(rng.second == it->second) {
				continue;
			}
			else if(union_once) {
				return false;
			}
			else if(Interval<int>::CanUnion(rng.second, it->second)) {
				union_once = true;
			}
			else {
				return false;
			}
		}
	}

	return true;
}

void Deg::Runtime::Math::Set::MergeOne(Conjunction& target, const Conjunction& c) {
	for(auto& rng : target.Clauses) {
		auto it = c.Clauses.find(rng.first);
		if(it != c.Clauses.end()) {
			rng.second = Interval<int>::Union(rng.second, it->second);
		}
		else {
			rng.second = Interval<int>(std::numeric_limits<int>::lowest(), std::numeric_limits<int>::max());
		}
	}
}

bool Deg::Runtime::Math::Set::TryMerge() {
	for(size_t i = 0; i < Disjunction.size(); ++i) {
		for(size_t j = i + 1; j < Disjunction.size();) {
			if(CanMerge(Disjunction[i], Disjunction[j])) {
				MergeOne(Disjunction[i], Disjunction[j]);
				if(Disjunction.size() - 1 > j) {
					Disjunction[j] = Disjunction[Disjunction.size() - 1];
				}

				Disjunction.pop_back();
				return true;
			}
			else {
				++j;
			}
		}
	}

	return false;
}

void Deg::Runtime::Math::Set::Merge() {
	while(TryMerge());
}

void Deg::Runtime::Math::Set::ReduceOne(Conjunction& target) {
	for(auto it = target.Clauses.begin(); it != target.Clauses.end();) {
		if(it->second.bottom == std::numeric_limits<int>::lowest() && it->second.top == std::numeric_limits<int>::max()) {
			it = target.Clauses.erase(it);
		}
		else {
			++it;
		}
	}
}

void Deg::Runtime::Math::Set::Reduce() {
	Disjoin();
	Merge();

	for(auto& conj : Disjunction) {
		ReduceOne(conj);
	}

	auto it = std::remove_if(Disjunction.begin(), Disjunction.end(),
			[](const Conjunction& val) { return val.IsEmpty(); });
	Disjunction.erase(it, Disjunction.end());

	return;
}

Deg::Runtime::Math::Set::Set() {
	return;
}

Deg::Runtime::Math::Set::Set(unsigned int field, Relation relation, int value) {
	switch(relation) {
	case Relation::Less:
		Disjunction.emplace_back(field, std::numeric_limits<int>::lowest(), value);
		break;

	case Relation::LessEqual:
		Disjunction.emplace_back(field, std::numeric_limits<int>::lowest(), value + 1);
		break;

	case Relation::Greater:
		Disjunction.emplace_back(field, value + 1, std::numeric_limits<int>::max());
		break;

	case Relation::GreaterEqual:
		Disjunction.emplace_back(field, value, std::numeric_limits<int>::max());
		break;

	case Relation::Equal:
		Disjunction.emplace_back(field, value, value + 1);
		break;

	case Relation::NotEqual:
		Disjunction.emplace_back(field, std::numeric_limits<int>::lowest(), value);
		Disjunction.emplace_back(field, value + 1, std::numeric_limits<int>::max());
		break;
	}
}

bool Deg::Runtime::Math::Set::IsEmpty() const {
	for(const auto& em : Disjunction) {
		if(!em.IsEmpty()) {
			return false;
		}
	}

	return true;
}

bool Deg::Runtime::Math::Set::IsSubsetOf(const Set& s) const {
	for(const auto& em : Disjunction) {
		// Each conjunction must be the subset of a conjunction in s.
		bool is_subset = false;

		for(const auto& en : s.Disjunction) {
			if(em.IsSubsetOf(en)) {
				is_subset = true;
				break;
			}
		}

		if(!is_subset) {
			return false;
		}
	}

	return true;
}

bool Deg::Runtime::Math::Set::operator==(const Set& s) const {
	return IsSubsetOf(s) && s.IsSubsetOf(*this);
}

bool Deg::Runtime::Math::Set::operator!=(const Set& s) const {
	return !(*this == s);
}

Deg::Runtime::Math::Set Deg::Runtime::Math::Set::operator&(const Set& s) const {
	// Intersection
	Set rv;
	for(const auto& cj : Disjunction) {
		for(const auto& scj : s.Disjunction) {
			Conjunction c = cj;
			for(const auto& sclause : scj.Clauses) {
				auto it = c.Clauses.find(sclause.first);
				if(it == c.Clauses.end()) {
					// No such clause
					c.Clauses[sclause.first] = sclause.second;
				}
				else {
					it->second = Interval<int>::Intersect(it->second, sclause.second);
				}
			}

			rv.Disjunction.push_back(c);
		}
	}

	rv.Reduce();
	return rv;
}

Deg::Runtime::Math::Set Deg::Runtime::Math::Set::operator|(const Set& s) const {
	Set rv;
	rv.Disjunction.insert(rv.Disjunction.end(), Disjunction.begin(), Disjunction.end());
	rv.Disjunction.insert(rv.Disjunction.end(), s.Disjunction.begin(), s.Disjunction.end());
	rv.Reduce();
	return rv;
}

Deg::Runtime::Math::Set Deg::Runtime::Math::Set::operator-(const Set& s) const {
	if(s.IsEmpty()) {
		return *this;
	}

	Set rv;

	std::vector<Conjunction> output;
	std::vector<Conjunction> current = Disjunction;

	for(const auto& dis : s.Disjunction) {
		output.clear();

		for(const auto& one : current) {
			DisjoinOne(one, dis, output);
		}

		std::swap(output, current);
	}

	std::swap(rv.Disjunction, current);
	rv.Reduce();
	return rv;
}

std::ostream& Deg::Runtime::Math::operator<<(std::ostream& os, const Set& s) {
	std::stringstream ss;
	ss << "{";

	bool p_dis_or = false;
	for(const auto& dis : s.Disjunction) {
		if(p_dis_or) {
			ss << "v";
		}
		else {
			p_dis_or = true;
		}

		ss << "(";

		bool p_con_and = false;
		for(const auto& con : dis.Clauses) {
			if(p_con_and) {
				ss << "^";
			}
			else {
				p_con_and = true;
			}

			ss << con.first << ":[" << con.second.bottom << "," << con.second.top << "]";
		}

		ss << ")";
	}

	ss << "}";
	return os << ss.str();
}
<|endoftext|>