Exemple #1
0
// Compute the stable models of the program
//    a :- not b.
//    b :- not a.
void example1() {
	// The ProgramBuilder lets you define logic programs.
	// It preprocesses logic programs and converts them
	// to the internal solver format.
	// See program_builder.h for details.
	Clasp::ProgramBuilder api;

	// Among other things, SharedContext maintains a Solver object
	// which hosts the data and functions for CDNL answer set solving.
	// SharedContext also contains the symbol table which stores the
	// mapping between atoms of the logic program and the
	// propositional literals in the solver.
	// See shared_context.h for details.
	Clasp::SharedContext  ctx;

	// startProgram must be called once before we can add atoms/rules
	api.startProgram(ctx);

	// Populate symbol table. Each atoms must have a unique id, the name is optional.
	// The symbol table then maps the ids to the propositional
	// literals in the solver.
	api.setAtomName(1, "a");
	api.setAtomName(2, "b");

	// Define the rules of the program.
	api.startRule(Clasp::BASICRULE).addHead(1).addToBody(2, false).endRule();
	api.startRule(Clasp::BASICRULE).addHead(2).addToBody(1, false).endRule();

	// Once all rules are defined, call endProgram() to load the (simplified)
	// program into the context object.
	api.endProgram();
	if (api.dependencyGraph() && api.dependencyGraph()->nodes() > 0) {
		// The program is non tight - add unfounded set checker.
		Clasp::DefaultUnfoundedCheck* ufs = new Clasp::DefaultUnfoundedCheck();
		// Register with solver and graph & transfer ownership.
		ufs->attachTo(*ctx.master(), api.dependencyGraph());
	}

	// For printing answer sets.
	AspOutPrinter printer;

	// Since we want to compute more than one
	// answer set, we need an enumerator.
	// See enumerator.h for details
	ctx.addEnumerator(new Clasp::BacktrackEnumerator(0,&printer));
	ctx.enumerator()->enumerate(0);

	// endInit() must be called once before the search starts.
	ctx.endInit();

	// Aggregates some solving parameters, e.g.
	//  - restart-strategy
	//  - ...
	// See solve_algorithms.h for details.
	Clasp::SolveParams    params;

	// solve() starts the search for answer sets. It uses the
	// given parameters to control the search.
	Clasp::solve(ctx, params);
}
Exemple #2
0
// Compute the stable models of the program
//    a :- not b.
//    b :- not a.
void example1(bool basicSolve) {
	// LogicProgram provides the interface for
	// defining logic programs.
	// It also preprocesses the program and converts it
	// to the internal solver format.
	// See logic_program.h for details.
	Clasp::Asp::LogicProgram lp;
	Potassco::RuleBuilder rb;

	// Among other things, SharedContext maintains a Solver object
	// which hosts the data and functions for CDNL answer set solving.
	// See shared_context.h for details.
	Clasp::SharedContext ctx;

	// startProgram must be called once before we can add atoms/rules
	lp.startProgram(ctx);

	// Define the rules of the program.
	Potassco::Atom_t a = lp.newAtom();
	Potassco::Atom_t b = lp.newAtom();
	lp.addRule(rb.start().addHead(a).addGoal(Potassco::neg(b)));
	lp.addRule(rb.start().addHead(b).addGoal(Potassco::neg(a)));

	// Populate output table.
	// The output table defines what is printed for a literal
	// that is part of an answer set.
	lp.addOutput("a", a);
	lp.addOutput("b", b);
	// It is not limited to atoms. For example, the following
	// statement results in the ouput "~b" whenever b is not
	// in a stable model.
	lp.addOutput("~b", Potassco::neg(b));
	// And we always want to have "eureka"...
	lp.addOutput("eureka", Potassco::toSpan<Potassco::Lit_t>());

	// Once all rules are defined, call endProgram() to load the (simplified)
	// program into the context object.
	lp.endProgram();

	// Since we want to compute more than one
	// answer set, we need an enumerator.
	// See enumerator.h for details
	Clasp::ModelEnumerator enumerator;
	enumerator.init(ctx);

	// We are done with problem setup.
	// Prepare for solving.
	ctx.endInit();

	if (basicSolve) {
		std::cout << "With Clasp::BasicSolve" << std::endl;
		// BasicSolve implements a basic search for a model.
		// It handles the various strategies like restarts, deletion, etc.
		Clasp::BasicSolve solve(*ctx.master());
		// Prepare the solver for enumeration.
		enumerator.start(solve.solver());
		while (solve.solve() == Clasp::value_true) {
			// Make the enumerator aware of the new model and
			// let it compute a new constraint and/or backtracking level.
			if (enumerator.commitModel(solve.solver())) { printModel(ctx.output, enumerator.lastModel()); }
			// Integrate the model into the search and thereby prepare
			// the solver for the search for the next model.
			enumerator.update(solve.solver());
		}
		std::cout << "No more models!" << std::endl;
	}
	else {
		std::cout << "With Clasp::SequentialSolve" << std::endl;
		// SequentialSolve combines a BasicSolve object,
		// which implements search for a model and handles
		// various strategies like restarts, deletion, etc.,
		// with an enumerator to provide more complex reasoning,
		// like enumeration or optimization.
		Clasp::SequentialSolve solve;
		solve.setEnumerator(enumerator);
		// Start the solve algorithm and prepare solver for enumeration.
		solve.start(ctx);
		// Extract and print models one by one.
		while (solve.next()) {
			printModel(ctx.output, solve.model());
		}
		if (!solve.more()) {
			std::cout << "No more models!" << std::endl;
		}
	}
}