Written from scratch SAT solver (b)

Written from scratch SAT solver (b)

Previous address

File parser

On the code:

//
// Dimacs parser.
//filename:DimacsParser.h
//
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cassert>
#include "common.h"

#ifndef DPLL_DIMACSPARSER_H
#define DPLL_DIMACSPARSER_H


class DimacsParser {
public:
    /**
     * Parse a dimacs file.
     * @param file_name dimacs file name
     * @return a parsed formula (if succeeds)
     */
    static formula parse(const std::string &file_name) {
        std::ifstream fin(file_name);
        if (!fin) {
            std::cerr << "file not found: " << file_name << "'" << std::endl;
            std::exit(1);
        }

        int n = 0, m = 0;
        while (!fin.eof()) {
            char ch;
            fin >> ch;

            if (ch == 'c') { // c-line: comment
                char buf[1024];
                fin.getline(buf, 1024);
            } else if (ch == 'p') { // p-line: clauses will begin
                std::string buf;
                fin >> buf;
                assert(buf == "cnf");
                fin >> n >> m;
                break;
            } else { // unexpected line
                std::cerr << "parse error at char '" << ch << "'" << std::endl;
                std::exit(1);
            }
        }

        // clauses begin
        std::vector<clause> clauses;
        for (int i = 0; i < m; i++) {
            clause c;
            while (!fin.eof()) {
                int v;
                fin >> v;
                if (v == 0) {
                    clauses.push_back(c);
                    break;
                }
                assert(VAR(v) <= n);
                c.push_back(v);
            }
        }
        assert(clauses.size() == m);

        return formula(n, clauses);
    }
};


#endif //DPLL_DIMACSPARSER_H

assert macro

Prototype assert macro defined in <assert.h> in its role if it returns an error condition, the program execution is terminated, prototype definition:

#include <assert.h>
void assert( int expression );

Role assert that now calculate expression expression, if it is false (that is, 0), then it Xianxiang stderr print an error message, and then terminate the program by calling abort.
Consider the following list of procedures badptr.c:

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int main( void )
{
       FILE *fp;
    
       fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件
       assert( fp );                           //所以这里不会出错
       fclose( fp );
    
       fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开文件失败
       assert( fp );                           //所以这里出错
       fclose( fp );                           //程序永远都执行不到这里来
       return 0;
}

Execute the file, the output:

[root@localhost error_process]# gcc badptr.c 
[root@localhost error_process]# ./a.out 
a.out: badptr.c:14: main: Assertion `fp'' failed.

The disadvantage of using assert that greatly affect the performance of the program of frequent invocation, additional overhead.
After commissioning, by inserting before the statement #define NDEBUG comprising #include <assert.h> to disable assert call, the following sample code:

#include <stdio.h>
#define NDEBUG
#include <assert.h>

Summary and Usage Notes:

  • Inspection parameters passed at the beginning of the legitimacy of function
    such as:
int resetBufferSize(int nNewSize)
{
//功能:改变缓冲区大小,
//参数:nNewSize 缓冲区新长度
//返回值:缓冲区当前长度 
//说明:保持原信息内容不变     nNewSize<=0表示清除缓冲区
assert(nNewSize >= 0);
assert(nNewSize <= MAX_BUFFER_SIZE);
...
}
  • Each test only assert a condition, because at the same time check more than one condition, if the assertion failure, not intuitive judgments which fail condition
    is not good:
assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize);

it is good:

assert(nOffset >= 0);
assert(nOffset+nSize <= m_nInfomationSize);
  • The statement can not be used to change the environment, because only in DEBUG assert a force, if to do so, will have problems using the program in a real run
    error:
assert(i++ < 100)

This is because if an error occurs, such as i = 100, then this statement will not be executed before the execution, then i ++ This command is not executed.
correct:

assert(i < 100)
         i++;
  • and the following statement should assert blank line, to form a consistent and logical sense of visual
  • In some places, assert can not replace the filter conditions
Published 94 original articles · won praise 69 · views 110 000 +

Guess you like

Origin blog.csdn.net/swy_swy_swy/article/details/104979621