英文题目跪求解答
困惑的小h 2013-12-06 07:51:34 给了四个hpp文件,要求编辑出对应的四个对应的cpp文件,每一块都有相应注释,要求用pointer互指,使make.cpp可以成功compile。编译环境最好是linux(g++)。输出结果应为true或false。跪求解答。题目要求如下:
This is the main exercise. As mentioned, the exercise practices copy construction. But it also has some aspects of input reading. You are asked to implement a package that will allow to implement a simple satisfiability solver (look up sat solving, links recommended by Alexey here and here). Essentially, the data structure implements a Boolean formula over Boolean variables in a certain format (CNF). The functionality that is added is particularly suitable to implement (very basic) solvers that can tell whether a given formula has an assignment that renders the formula true.
The classes that are required are:
1. Variable - a Boolean variable. A variable may be unset, which means that it's value is (currently) unknown, or set, in which case it is either true or false.
2. Literal - this is either a variable or a negated variable.
3. Clause - this is a disjunction of literals. In our package the clause is an array of literals. It has to be memory efficient (i.e., not allocate space for more literals than it actually has).
In more efficient sat solvers, when a variable is set it notifies all the clauses in which it appears. For that, our variables are going to contain pointers to the clauses that contain them. Again, the Variable should not allocate more space than required for storing these pointers.
4. Formula - this is the main class here. A formula is the conjunction of a set of clauses. It also contains all the variables that appears in these clauses in order to coordinate the solving process. Again, the containers in the Formula should not be larger than required.
Notice that some of the options are quite advanced. For example, force in Clause, and resolve in Formula. As mentioned, the main point of the exercise is in the copy constructor of Formula. So you should invest most of your effort in that. If the different copy constructors work fine, then proceed to the more advanced options that go in the direction of sat solving.
Technically, I have created the header files of all these classes. You have to complete them with additional members and complete the implementations. You will have to submit eight files: Variable.*pp, Literal.*pp, Clause.*pp, and Formula.*pp. You can submit one additional file called Solver.cpp. This file can contain your own version of a sat solver that improves on the one that I included below. The Solver.cpp file has to contain a main and it will be compiled using the same Makefile that is supplied below. The header files include detailed descriptions of the functions that you are required to implement.
下面是四个hpp文件和main.cpp文件:
Variable.hpp:
/*
* Variable.hpp
*
* Created on:
* Author:
*/
#ifndef VARIABLE_HPP_
#define VARIABLE_HPP_
#include <iosfwd>
#include <string>
class Variable;
#include "Clause.hpp"
class Variable {
public:
// This is a basic Boolean variable
// It has an ID and is either set or unset (i.e., known or unknonw)
// If it is set, it can be true or false
// It also holds pointers to all the clauses that it appears
// in.
Variable();
// Initializes the identifier
// The identifier of a real variable cannot be 0!
Variable(unsigned int);
// Copies the identifier and the status of the variable
// Does not copy the clauses (deep copy is orchestrated by
// formula)
Variable(const Variable &);
// Clean you mess
~Variable();
// Return the value of the variable
// If the variable is not set return whatever you want
bool value() const;
// Return whether the variable is set or not
bool isSet() const;
// Set the variable to the given value
void set(bool);
// Unset the variable
void unset();
// Update the list of clauses in which the variable appears
void addedToClause(Clause* cl);
// In how many clauses does the variable appear
unsigned int numClauses() const;
// Return a pointer to the i-th clause the variable
// is in.
// Or NULL if there is no such clause
Clause* clause(unsigned int);
// Return the id
unsigned int id() const;
// output ?/0/1 accoring to the set/unset value.
std::string toString() const;
private:
// Add your own data members and member functions.
};
std::ostream& operator<<(std::ostream&, const Variable&);
#endif /* VARIABLE_HPP_ */
Formula.hpp:
/*
* Formula.hpp
*
* Created on:
* Author:
*/
#ifndef FORMULA_HPP_
#define FORMULA_HPP_
#include <iosfwd>
#include <string>
class Formula;
#include "Clause.hpp"
#include "Variable.hpp"
// A formula has a given set of variables
// and clauses that use these variables.
// The total data structure that we are developing has a formula
// but it also contains a partial assignment to the
// variables appearing in the formula.
// The assignment is partial as some variables could be
// unset.
//
// The partial assignment may be sufficient to deduce that
// the formula is satisfied but in most cases it is not sufficient.
//
// In case that the partial assignment is not sufficient there
// may be a fuller assignment that does satisfy the formula.
// A SAT solver (see main.cpp) tries to extend the
// current assignment to a fuller assignment that satisfies
// the formula.
//
// Some of the functions, such as resolve(), tries to increase
// the assignment to a fuller assignment based on the
// constraints that the formula induces.
//
class Formula {
public:
Formula();
// A deep copy.
// This deep copy should orchestrate all the other classes so
// that you get a deep copy of the entire formula.
Formula(const Formula&);
// Clean your mess
~Formula();
// If the variable exists returns true
// If the variable does not exist adds it and
// return false
bool addVar(unsigned int);
// returns false if the variable does not exist
// If the variable does exist sets the pointer
// reference to the pointer to this variable
bool findVar(unsigned int, Variable*&) const;
// Returns the id of an unset variable
// If there is no unset variable it returns 0.
unsigned int firstUnsetVar();
// Adds a clause of size size
// The values in the array are the identifiers
// of the variables.
// The identifier has negative value if it is negated
// it has positive value if it is not negated
void addClause(unsigned int size, int* array);
// Set the variable id to the value
// If the variable does not exist return false
// Otherwise set the variable and return true
bool setVar(unsigned int id,bool value);
// Unset the variable id
// If the variable does not exist return false
// Otherwise set the variable and return true
bool unsetVar(unsigned int id);
// Return the value of variable id
// If there is no such variable return false
bool value(unsigned int id);
// Is variable id set?
// If there is no such variable return false
bool isSet(unsigned int) const;
// Is the formula satisfied?
// The formula is satisfied if all the clauses in it are
// satisfied
bool sat() const;
// Go over all clauses and check if some clause
// forces the value of a variable.
// If it does then set the value to the forced value.
// Continue until no more resolutions are possible.
void resolve();
// Output the formula in dimacs format (see below)
// You can write whatever you want as initial comments
std::string toString() const;
// Read a formula in dimacs format
// A formula can start with several lines of comments
// that are identified by the first character 'c'
// You should ignore these lines.
// Then, the formula has a line of the format:
// p cnf numVars numClauses
// numVars is the number of variables in the formula
// numClauses is the number of clauses that you need to read
//
// No comments appear after this line with p
// The only thing that appears from now on are numbers
// according to the format explained below. If anything
// else appears the reading should fail and the stream
// should be left with an error state.
//
// Then there is a list of clauses each in a separate line
// The structure of a clause is:
// number number number .... number 0
//
// That is, you have a sequence of identifiers as positive or negative
// numbers.
// The sequence ends with a 0.
// You are allowed to ignore whatever appears after the 0 until
// the next line.
// Line length is bounded by 1000.
// This sequence represents a clause in which:
// If the number is negative (e.g., -5) this means that there
// is literal with a negated variable of the identifier that
// matches the absolute
// value of the number (5 in the example).
// If the number is positive (e.g., 5) this means that there
// is a literal with a varialbe of the identifier that
//
// If there are faults during reading the formula you should leave
// the formula in parameter (reference) unchanged and leave the stream
// with the appropriate error state.
//
// Notice the following two faults that should result in failure
// to read:
// 1. The formula has a too small number of clauses
// 2. The number of variables declared is different
// from the actual number of variables appearing
// in the different clauses.
friend std::istream& operator>>(std::istream&, Formula&);
private:
// Add your own data members and member functions.
};
// Write the toString
std::ostream& operator<<(std::ostream&, const Formula&);
#endif /* FORMULA_HPP_ */
(未完)