英文题目跪求解答

困惑的小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_ */
(未完)
...全文
314 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
max_min_ 2013-12-06
  • 打赏
  • 举报
回复
引用 7 楼 u012863458 的回复:
[quote=引用 4 楼 max_min_ 的回复:] 先把英文翻译搞定了,然后再想想题目的意思,然后再来问问思路 自己写下代码就好了!
努力了一个礼拜了,从来没学过编程,英文是没啥问题,但是编程的东西根本看不懂。。。[/quote] 把英文的题目要求翻译过来!贴出来看看需求是啥,我帮你参考下!
困惑的小h 2013-12-06
  • 打赏
  • 举报
回复
引用 3 楼 truelance 的回复:
找人做作业是不好的习惯. 哪里不会把那部分单独拿出来问. 这么长谁有空看啊
抱歉,我从来没学过编程,确实是不会的太多了,根本不知道该如何下手。。。哎。。。
困惑的小h 2013-12-06
  • 打赏
  • 举报
回复
引用 2 楼 adeng1919 的回复:
那么长
抱歉哈,没办法了,我要是自己能搞定也不在这丢人了。。。
困惑的小h 2013-12-06
  • 打赏
  • 举报
回复
引用 4 楼 max_min_ 的回复:
先把英文翻译搞定了,然后再想想题目的意思,然后再来问问思路 自己写下代码就好了!
努力了一个礼拜了,从来没学过编程,英文是没啥问题,但是编程的东西根本看不懂。。。
baichi4141 2013-12-06
  • 打赏
  • 举报
回复
被楼主召唤过来 表示无意替人写作业 就这样
赵4老师 2013-12-06
  • 打赏
  • 举报
回复
参考g++相关源代码。
max_min_ 2013-12-06
  • 打赏
  • 举报
回复
先把英文翻译搞定了,然后再想想题目的意思,然后再来问问思路 自己写下代码就好了!
熊熊大叔 2013-12-06
  • 打赏
  • 举报
回复
找人做作业是不好的习惯. 哪里不会把那部分单独拿出来问. 这么长谁有空看啊
懒懒的吉他手 2013-12-06
  • 打赏
  • 举报
回复
那么长
worldy 2013-12-06
  • 打赏
  • 举报
回复
唉,送到百度 翻译或者什么翻译里,帮 你翻译一下吧
困惑的小h 2013-12-06
  • 打赏
  • 举报
回复
Literal.hpp: /* * Literal.hpp * * Created on: * Author: */ #ifndef LITERAL_HPP_ #define LITERAL_HPP_ #include <iosfwd> #include <string> class Literal; #include "Variable.hpp" // A literal is a variable that is negated or not. // Accordingly it holds a pointer to a variable and // a Boolean variable that tells us if the // variable is negated or not. // For example, a literal could be (not 5). That is, this literal // is true if variable 5 is false and vice versa. // Or, a literal could be 7. That is, this literal is // true if variable 7 is true. class Literal { public: Literal(); // Initialize the variable and the polarity // If polarity is true the variable is not negated // If polarity is false the variable is negated Literal(Variable* var,bool); // Clean up your mess ~Literal(); // Return the id of the variable unsigned int var() const; // Return the polarity unsigned int polarity() const; // Return whether the literal is satisfied or not // If the variable is not negated and it is set to true // then the literal is sat // If the variable is negated and it is set to false // the the literal is sat // In all other cases it is unsat. bool sat() const; // Set the variable void setVar(Variable*); // Set the polarity // If polarity is true the variable is not negated // If polarity is false the variable is negated void setPolarity(bool); // -id if the variable is negated // id if the variable is not negated std::string toString() const; private: // No need to implement this Literal(const Literal&); // Add your own private data members and member functions }; // output the toString method std::ostream& operator<<(std::ostream&, const Literal&); #endif /* LITERAL_HPP_ */ Clause.hpp: /* * Clause.hpp * * Created on: * Author: */ #ifndef CLAUSE_HPP_ #define CLAUSE_HPP_ #include <iosfwd> #include <string> class Clause; #include "Literal.hpp" #include "Formula.hpp" // A clause is a list of literals that belong to a certain // Formula. // It holds a pointer to the formula and a list of the literals // that compose it // Semantically, it is the disjunction of all the literals // that appear in it. // So if one of this literals is satisfied, the clause is // satisfied. // As variables have unknown values, the clause could: // 1. Be satisfied by the current assignment // 2. Have some variables unset // 3. Have all variables set to the wrong values (from the clause's // point of view) and be unsatisfiable. // The interesting case is 2. // In that case, if only one variable has an unknown value // then the clause, in order to be satisfied, forces the value // of this variable to true/false according to the polarity // of this variable in the clause (see force below) class Clause { public: // Initialize the formula Clause(Formula*); // Deep copy the clause that (may) belong to a different // formula. // This clause belongs to the given formula. // Make sure that the formula to which this clause belongs // has the variables that are included in the clause. Clause(const Clause&, Formula*); // Clean up your mess ~Clause(); // If the clause is not satisfied and // it has just one literal whose variable is unset // then it forces the value of this variable. // The function returns the number of the variable // that needs setting and the value that it needs setting // in order to satisfy the clause unsigned int forceSet(bool &val); // Add a literal with the given variable and this polarity void addLiteral(Variable* var,bool polarity); // Is the clause satisfied? // It is enough to have one literal satified // in order to be satisfied bool sat() const; // A variable that may or may not appear in this clause // notifies the clause that it is set and the value it is // set to. // Most implementations should not really bother with this function. // Just include an implementation that doesn't do // anything. // This is intended for people who implement two literal watching. void notifySet(unsigned int id, bool val); // A variable that may or may not appear in this clause // notifies the clause that it is unset. // Most implementations should not really bother with this function. // Just include an implementation that doesn't do // anything. // This is intended for people who implement two literal watching. void notifyUnset(unsigned int id); // Output all the literals the way literals are supposed to be printed std::string toString() const; private: // Don't implement these if you don't want to Clause(); Clause(const Clause&); // Add your own data members and member functions. }; // Use the toString function std::ostream& operator<<(std::ostream&, const Clause&); #endif /* CLAUSE_HPP_ */ main.cpp: /* * surgery.cpp * * Created on: * Author: */ #include <iostream> #include <fstream> #include <string> #include "Formula.hpp" using std::cout; using std::cin; using std::cerr; using std::endl; using std::string; using std::ifstream; // Notice the by value! bool solve(Formula f) { f.resolve(); if (f.sat()) { return true; } unsigned int id = f.firstUnsetVar(); if (id) { f.setVar(id,true); if (solve(f)) { return true; } f.setVar(id,false); if (solve(f)) { return true; } } return false; } int main() { Formula f; ifstream inFile("form1.txt"); if (!inFile) { cerr << "Failed to open file!" << endl; return 1; } inFile >> f; //cout << "The formula is:" << endl; //cout << f; Formula copy(f); cout << "\n\n\n" << copy; if (solve(f)) { cout << "satisfiable"; } else { cout << "unsatisfiable"; } }
signforlin 2013-12-06
  • 打赏
  • 举报
回复
引用 3 楼 truelance 的回复:
找人做作业是不好的习惯. 哪里不会把那部分单独拿出来问. 这么长谁有空看啊
哪里不会点哪里呗
lm_whales 2013-12-06
  • 打赏
  • 举报
回复
这是数理逻辑题用C,C++去处理。 首先要对数理逻辑,搞清楚,不清楚去看。
困惑的小h 2013-12-06
  • 打赏
  • 举报
回复
引用 10 楼 max_min_ 的回复:
[quote=引用 7 楼 u012863458 的回复:] [quote=引用 4 楼 max_min_ 的回复:] 先把英文翻译搞定了,然后再想想题目的意思,然后再来问问思路 自己写下代码就好了!
努力了一个礼拜了,从来没学过编程,英文是没啥问题,但是编程的东西根本看不懂。。。[/quote] 把英文的题目要求翻译过来!贴出来看看需求是啥,我帮你参考下![/quote] 抱歉,对计算机术语不是很了解,翻译的不好,我已经尽力了,请多多包含。小弟万分感激。
困惑的小h 2013-12-06
  • 打赏
  • 举报
回复
这个题目是练习拷贝构造。但它也有一些输入读取的部分。要求编译一个可以实现一个简单sat solver的包裹。数据结构要在一个确定的CNF(合取范式)格式里面实现包含Boolean变量的Boolean公式。需要添加的功能性是实现让这个solver可以判断给出的公式能否为真。下面是四个类: 1. Variable- 一个boolean变量。如果一个变量没有被设定,那么这个变量就未知。如果一个变量被设定,那么这个变量就可以确定其真假。 2.Literal- 这个是确定变量有无符号。 3. Clasue-这是Literal的分离。在包裹里面,Clause是一个Literal组成的数组,它必须是节约内存的(不在多余的leteral身上浪费内存)。在更高效的sat solver里面,如果一个变量被设定了,那么所有相应的clause要出现在对应的位置。变量指向含有他们的clause。在这里,变量是不应该把内存分配给指针的。(我理解的clause就是要给合取范式的变量加括号的,比如(A||B)&&(C||D)) 4. Formula-这是主类。一个formula是一系列clause的合体。它也包含对应这些clause的变量。

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧