Skip to content

Commit 6243d35

Browse files
authored
Merge pull request #41 from msoeken/cnf
Generate CNF.
2 parents a4fb03c + ea0d7e9 commit 6243d35

File tree

9 files changed

+257
-1
lines changed

9 files changed

+257
-1
lines changed

docs/changelog.rst

+9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
Change Log
22
==========
33

4+
v0.4 (not yet released)
5+
-----------------------
6+
7+
* Constructors: ``create_from_clauses``, ``create_characteristic``
8+
`#41 <https://github.com/msoeken/kitty/pull/41>`_
9+
10+
* CNF generation: ``cnf_characteristic``
11+
`#41 <https://github.com/msoeken/kitty/pull/41>`_
12+
413
v0.3 (February 25, 2018)
514
------------------------
615

docs/cnf.rst

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CNF representations
2+
===================
3+
4+
The header ``<kitty/cnf.hpp>`` implements methods to compute conjunctive normal
5+
forms (CNF).
6+
7+
.. doc_brief_table::
8+
cnf_characteristic
9+
10+

docs/constructors.rst

+2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ The header ``<kitty/constructors.hpp>`` implements operations to construct truth
1111
create_random
1212
create_from_words
1313
create_from_cubes
14+
create_from_clauses
1415
create_majority
1516
create_threshold
1617
create_equals
1718
create_symmetric
1819
create_from_chain
20+
create_characteristic
1921

2022

docs/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Welcome to kitty's documentation!
3232
permutation
3333
esop
3434
isop
35+
cnf
3536
reference
3637

3738
Indices and tables

include/kitty/cnf.hpp

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* kitty: C++ truth table library
2+
* Copyright (C) 2017-2018 EPFL
3+
*
4+
* Permission is hereby granted, free of charge, to any person
5+
* obtaining a copy of this software and associated documentation
6+
* files (the "Software"), to deal in the Software without
7+
* restriction, including without limitation the rights to use,
8+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the
10+
* Software is furnished to do so, subject to the following
11+
* conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be
14+
* included in all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23+
* OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
26+
/*!
27+
\file cnf.hpp
28+
\brief Implements methods to compute conjunctive normal forms (CNF)
29+
30+
\author Mathias Soeken
31+
*/
32+
33+
#pragma once
34+
35+
#include <vector>
36+
37+
#include "cube.hpp"
38+
#include "isop.hpp"
39+
#include "operators.hpp"
40+
41+
namespace kitty
42+
{
43+
44+
/*! \brief Create CNF of the characteristic function
45+
46+
Creates a CNF representation for the characteritic function of the input
47+
function, also known as Tseytin transformation. To obtain small CNF,
48+
an ISOP is computed.
49+
50+
\param tt Truth table
51+
*/
52+
template<typename TT>
53+
std::vector<cube> cnf_characteristic( const TT& tt )
54+
{
55+
std::vector<cube> cubes;
56+
detail::isop_rec( tt, tt, tt.num_vars(), cubes );
57+
58+
for ( auto& cube : cubes )
59+
{
60+
cube._bits = ~cube._bits & cube._mask;
61+
cube.add_literal( tt.num_vars(), true );
62+
}
63+
64+
const auto end = cubes.size();
65+
66+
detail::isop_rec( ~tt, ~tt, tt.num_vars(), cubes );
67+
68+
for ( auto i = end; i < cubes.size(); ++i )
69+
{
70+
auto& cube = cubes[i];
71+
cube._bits = ~cube._bits & cube._mask;
72+
cube.add_literal( tt.num_vars(), false );
73+
}
74+
75+
return cubes;
76+
}
77+
78+
} // namespace kitty

include/kitty/constructors.hpp

+77
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,59 @@ void create_from_cubes( TT& tt, const std::vector<cube>& cubes, bool esop = fals
294294
}
295295
}
296296

297+
/*! \brief Creates truth table from clause representation
298+
299+
A product-of-sum is represented as a vector of sums (called clauses).
300+
301+
An empty truth table is given as first argument to determine type
302+
and number of variables. Literals in sums that do not fit the
303+
number of variables of the truth table are ignored.
304+
305+
The clause representation only allows truth table sizes up to 32
306+
variables.
307+
308+
\param tt Truth table
309+
\param clauses Vector of clauses
310+
\param esop Use product of exclusive sums instead of POS
311+
*/
312+
template<typename TT>
313+
void create_from_clauses( TT& tt, const std::vector<cube>& clauses, bool esop = false )
314+
{
315+
/* we collect product terms for an (E)SOP, start with const0 */
316+
clear( tt );
317+
tt = ~tt;
318+
319+
for ( auto clause : clauses )
320+
{
321+
auto sum = tt.construct(); /* const1 of same size */
322+
323+
auto bits = clause._bits;
324+
auto mask = clause._mask;
325+
326+
for ( auto i = 0; i < tt.num_vars(); ++i )
327+
{
328+
if ( mask & 1 )
329+
{
330+
auto var = tt.construct();
331+
create_nth_var( var, i, !( bits & 1 ) );
332+
333+
if ( esop )
334+
{
335+
sum ^= var;
336+
}
337+
else
338+
{
339+
sum |= var;
340+
}
341+
}
342+
bits >>= 1;
343+
mask >>= 1;
344+
}
345+
346+
tt &= sum;
347+
}
348+
}
349+
297350
/*! \brief Constructs majority-n function
298351
299352
The number of variables is determined from the truth table.
@@ -660,4 +713,28 @@ bool create_from_chain( TT& tt, std::istream& in, std::string* error = nullptr )
660713
return true;
661714
}
662715
}
716+
717+
/*! \brief Creates characteristic function
718+
719+
Creates the truth table of the characteristic function, which contains one
720+
additional variable. The new output variable will be the most-significant
721+
variable of the new function.
722+
723+
\param tt Truth table for characteristic function
724+
\param from Input truth table
725+
*/
726+
template<typename TT, typename TTFrom>
727+
inline void create_characteristic( TT& tt, const TTFrom& from )
728+
{
729+
assert( tt.num_vars() == from.num_vars() + 1 );
730+
731+
auto var = tt.construct();
732+
create_nth_var( var, from.num_vars() );
733+
734+
auto ext = tt.construct();
735+
extend_to( ext, from );
736+
737+
tt = ~var ^ ext;
738+
}
739+
663740
} // namespace kitty

include/kitty/isop.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ namespace kitty
4040
{
4141

4242
/*! \cond PRIVATE */
43+
namespace detail
44+
{
4345
template<typename TT>
4446
TT isop_rec( const TT& tt, const TT& dc, uint8_t var_index, std::vector<cube>& cubes )
4547
{
@@ -99,6 +101,7 @@ TT isop_rec( const TT& tt, const TT& dc, uint8_t var_index, std::vector<cube>& c
99101

100102
return res2;
101103
}
104+
}
102105
/* \endcond */
103106

104107
/*! \brief Computes ISOP representation
@@ -113,7 +116,7 @@ template<typename TT>
113116
inline std::vector<cube> isop( const TT& tt )
114117
{
115118
std::vector<cube> cubes;
116-
isop_rec( tt, tt, tt.num_vars(), cubes );
119+
detail::isop_rec( tt, tt, tt.num_vars(), cubes );
117120
return cubes;
118121
}
119122

include/kitty/kitty.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "affine.hpp"
3939
#include "algorithm.hpp"
4040
#include "bit_operations.hpp"
41+
#include "cnf.hpp"
4142
#include "constructors.hpp"
4243
#include "cube.hpp"
4344
#include "esop.hpp"

test/cnf.cpp

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* kitty: C++ truth table library
2+
* Copyright (C) 2017-2018 EPFL
3+
*
4+
* Permission is hereby granted, free of charge, to any person
5+
* obtaining a copy of this software and associated documentation
6+
* files (the "Software"), to deal in the Software without
7+
* restriction, including without limitation the rights to use,
8+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the
10+
* Software is furnished to do so, subject to the following
11+
* conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be
14+
* included in all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23+
* OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
26+
#include <gtest/gtest.h>
27+
28+
#include <kitty/constructors.hpp>
29+
#include <kitty/cnf.hpp>
30+
#include <kitty/dynamic_truth_table.hpp>
31+
#include <kitty/static_truth_table.hpp>
32+
33+
#include "utility.hpp"
34+
35+
using namespace kitty;
36+
37+
class CNFTest : public kitty::testing::Test
38+
{
39+
};
40+
41+
TEST_F( CNFTest, small_cnf_dynamic )
42+
{
43+
auto f = from_hex( 3, "c2" );
44+
const auto cubes = cnf_characteristic( f );
45+
46+
dynamic_truth_table char1( f.num_vars() + 1 ), char2( f.num_vars() + 1 );
47+
create_from_clauses( char1, cubes );
48+
create_characteristic( char2, f );
49+
EXPECT_EQ( char1, char2 );
50+
}
51+
52+
TEST_F( CNFTest, random_cnf_dynamic )
53+
{
54+
dynamic_truth_table f( 10u ), f_c1( 11u ), f_c2( 11u );
55+
for ( auto i = 0; i < 50; ++i )
56+
{
57+
create_random( f );
58+
create_from_clauses( f_c1, cnf_characteristic( f ) );
59+
create_characteristic( f_c2, f );
60+
EXPECT_EQ( f_c1, f_c2 );
61+
}
62+
}
63+
64+
TEST_F( CNFTest, random_cnf_static )
65+
{
66+
static_truth_table<10> f;
67+
static_truth_table<11> f_c1, f_c2;
68+
for ( auto i = 0; i < 50; ++i )
69+
{
70+
create_random( f );
71+
create_from_clauses( f_c1, cnf_characteristic( f ) );
72+
create_characteristic( f_c2, f );
73+
EXPECT_EQ( f_c1, f_c2 );
74+
}
75+
}

0 commit comments

Comments
 (0)