BitMagic-C++
bv3vlogic.cpp
Go to the documentation of this file.
1/*
2Copyright(c) 2002-2017 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15
16For more information please visit: http://bitmagic.io
17*/
18
19/** \example bv3vlogic.cpp
20 Example demonstrates variety three-valued logic.
21 https://en.wikipedia.org/wiki/Three-valued_logic
22
23 <a href="https://en.wikipedia.org/wiki/Three-valued_logic">Three-valued logic</a>
24*/
25
26/*! \file bv3vlogic.cpp
27 \brief Example: Kleene algebra operations
28
29 BitMagic implements 3-value (Kleene) logic using two separate bit-vectors:
30 bit-vector of values and bit-vector of knowns.
31
32 bit-vector of vlaues contains 1s in the positions of true
33 bit-vector of NULLs contains 1s where values in known (or set)
34
35 The convention is that unknown elements (0s in the NULL vector) MUST NOT
36 have 1s in the corresponding positions of the value bit-vector so
37 "unknown TRUE" is not a correct situation.
38*/
39
40
41#include <iostream>
42#include <vector>
43#include <cassert>
44
45#include "bm.h"
46#include "bm3vl.h"
47#include "bmundef.h" /* clear the pre-proc defines from BM */
48
49using namespace std;
50
51/**
52 Print 3-value vector
53 */
54static
55void PrintKleeneVector(const bm::bvector<>& bv_v, const bm::bvector<>& bv_null)
56{
57 bm::bvector<>::enumerator en_n = bv_null.first();
58 auto prev = *en_n;
59 if (prev > 0)
60 prev = 0;
61
62 for ( ;en_n.valid(); ++en_n)
63 {
64 auto curr = *en_n;
65 for (auto i = prev; i < curr; ++i)
66 cout << i << ": NULL" << endl;
67 bool v = bv_v.test(curr);
68 cout << curr << ": " << (v ? "true" : "false") << endl;
69 prev = curr + 1;
70 } // for en_n
71
72 cout << endl;
73
74}
75
76/**
77 This demo shows how to use bm::set_value_kleene and bm::get_value_kleene
78 functions to set values into pair of vectors (value vector and knowns vector)
79
80 Kleene algebra operates on 3 values, which are by convention read as:
81 -1 (known false), 0 (unknown), 1 (known true).
82
83 bm::set_value_kleene takes a pair of vectors, position and an int value
84 to set value in a pair of bit-vectors representing value and knowns
85
86 Please note that this is the easy but relatively slow method to init the
87 vectors since because it uses random access initialization.
88 */
89static
91{
92 bm::bvector<> bv_v; // (true/false) values bit-vector
93 bm::bvector<> bv_null; // (known/unknown (or NULL) values bit-vector
94
95 int v = 0; // start with the unknown
96 for (unsigned i = 0; i < 10; ++i)
97 {
98 bm::set_value_kleene(bv_v, bv_null, i, v);
99 auto v1 = bm::get_value_kleene(bv_v, bv_null, i);
100 assert(v == v1); (void) v1;
101 v += 1;
102 if (v > 1)
103 v = -1;
104 }
105
107 bv_v.optimize(tb);
108 bv_null.optimize(tb);
109
110 PrintKleeneVector(bv_v, bv_null);
111}
112
113/**
114 Faster way to initialize Kleene bit-vectors via bulk_insert_iterator
115 */
116static
118{
119 bm::bvector<> bv_v; // (true/false) values bit-vector
120 bm::bvector<> bv_null; // (known/unknown (or NULL) values bit-vector
121
122 // use insert iterators to load the vectors
123 {
126
127 for (unsigned i = 0; i < 13; i+=3)
128 {
129 if (i & 1) // add only true values as indexes of set bits via insert iterator
130 {
131 iit_v = i;
132 }
133 // set the known bit for both true AND false values
134 iit_n = i;
135 }
136 // flush the insert iterators to empty the temp.buffers
137 // it is best to do it explicitly (it can throw exceptions)
138 iit_v.flush();
139 iit_n.flush();
140 }
141
142 // init used to guarantee that value bit-vector would not contain
143 // "unknown" true values, which is a requirement of BM library to be able to
144 // correct 3-value logical ANDs and ORs
145 //
146 // If you are absolutely sure that you did not set true values for unknowns
147 // then you do not need this call
148 //
149 bm::init_kleene(bv_v, bv_null);
150
151 // optimize bit-vectors after initalization
152 //
154 bv_v.optimize(tb);
155 bv_null.optimize(tb);
156
157 PrintKleeneVector(bv_v, bv_null);
158}
159
160/**
161 Generate Kleene vector (as two bit-vectors)
162*/
163static
165{
166 int v = 0; // start with the unknown
167 for (unsigned i = 0; i < 10; ++i)
168 {
169 bm::set_value_kleene(bv_v, bv_null, i, v);
170 v += 1;
171 if (v > 1)
172 v = -1;
173 } // for
174 // optimize bit-vectors after initalization
175 //
177 bv_v.optimize(tb);
178 bv_null.optimize(tb);
179}
180
181/**
182 Demo for 3-value logic (Kleene) NOT
183 */
184static
186{
187 bm::bvector<> bv_v; // (true/false) values bit-vector
188 bm::bvector<> bv_null; // (known/unknown (or NULL) values bit-vector
189
190 GenerateDemoVector(bv_v, bv_null);
191
192 cout << "Input vector:" << endl;
193 PrintKleeneVector(bv_v, bv_null);
194
195 bm::invert_kleene(bv_v, bv_null); // 3-value logic NOT
196
197 cout << "Inverted vector:" << endl;
198 PrintKleeneVector(bv_v, bv_null);
199}
200
201
202/**
203 Demo for 3-value logic (Kleene) AND
204
205 Kleene algebra AND
206 produces known FALSE when known FALSE meets UNKNOWN (false)
207 */
208static
210{
211 bm::bvector<> bv_v1; // (true/false) values bit-vector
212 bm::bvector<> bv_null1; // (known/unknown (or NULL) values bit-vector
213
214 GenerateDemoVector(bv_v1, bv_null1);
215
216 bm::bvector<> bv_v2; // (true/false) values bit-vector
217 bm::bvector<> bv_null2; // (known/unknown (or NULL) values bit-vector
218
219 bm::set_value_kleene(bv_v2, bv_null2, 0, 0); // idx = 0 (unknown)
220 bm::set_value_kleene(bv_v2, bv_null2, 1, 1); // idx = 1 (known true)
221 bm::set_value_kleene(bv_v2, bv_null2, 2, -1); // idx = 2 (known false)
222
223
224 bm::bvector<> bv_v_t, bv_null_t;
225 // bv_v_t := bv_v2 & bv_v1
226 bm::and_kleene(bv_v_t, bv_null_t, bv_v2, bv_null2, bv_v1, bv_null1); // 3-value logic AND
227
228 // bv_v2 and bv_null2 are modified in place:
229 // bv_v2 &= bv_v1
230 bm::and_kleene(bv_v2, bv_null2, bv_v1, bv_null1); // 3-value logic AND
231
232 bool b = bv_v_t.equal(bv_v2);
233 assert(b);
234 b = bv_null_t.equal(bv_null2);
235 assert(b);
236
237 cout << "AND vector:" << endl;
238 PrintKleeneVector(bv_v2, bv_null2);
239
240}
241
242/**
243 Demo for 3-value logic (Kleene) OR
244
245 Kleene algebra OR
246 produces known TRUE when known TRUE meets UNKNOWN (false)
247 */
248static
250{
251 bm::bvector<> bv_v1; // (true/false) values bit-vector
252 bm::bvector<> bv_null1; // (known/unknown (or NULL) values bit-vector
253
254 GenerateDemoVector(bv_v1, bv_null1);
255
256 bm::bvector<> bv_v2; // (true/false) values bit-vector
257 bm::bvector<> bv_null2; // (known/unknown (or NULL) values bit-vector
258
259 bm::set_value_kleene(bv_v2, bv_null2, 0, 1); // idx = 0 (known true)
260 bm::set_value_kleene(bv_v2, bv_null2, 1, 0); // idx = 1 (NULL)
261 bm::set_value_kleene(bv_v2, bv_null2, 2, -1); // idx = 2 (known false)
262
263 bm::bvector<> bv_v_t, bv_null_t;
264 // bv_v_t := bv_v2 | bv_v1
265 bm::or_kleene(bv_v_t, bv_null_t, bv_v2, bv_null2, bv_v1, bv_null1); // 3-value logic AND
266
267 // bv_v2 and bv_null2 are modified in place:
268 // bv_v2 |= bv_v1
269 bm::or_kleene(bv_v2, bv_null2, bv_v1, bv_null1); // 3-value logic OR
270
271 bool b = bv_v_t.equal(bv_v2);
272 assert(b);
273 b = bv_null_t.equal(bv_null2);
274 assert(b);
275
276
277 cout << "OR vector:" << endl;
278 PrintKleeneVector(bv_v2, bv_null2);
279
280}
281
282
283
284int main(void)
285{
286 try
287 {
288 cout << endl << "3VL Set values:" << endl << endl;
291
292 cout << endl << "3VL Invert vector:" << endl << endl;
294
295 cout << endl << "3VL AND:" << endl << endl;
297
298 cout << endl << "3VL OR:" << endl << endl;
300 }
301 catch(std::exception& ex)
302 {
303 std::cerr << ex.what() << std::endl;
304 }
305
306 return 0;
307}
Three-valued logic (3VL) operations.
Compressed bit-vector bvector<> container, set algebraic methods, traversal iterators.
#define BM_DECLARE_TEMP_BLOCK(x)
Definition: bm.h:47
pre-processor un-defines to avoid global space pollution (internal)
static void Set3VL_ValueDemo2()
Faster way to initialize Kleene bit-vectors via bulk_insert_iterator.
Definition: bv3vlogic.cpp:117
static void Set3VL_ORDemo()
Demo for 3-value logic (Kleene) OR.
Definition: bv3vlogic.cpp:249
static void Set3VL_AndDemo()
Demo for 3-value logic (Kleene) AND.
Definition: bv3vlogic.cpp:209
static void Set3VL_ValueDemo()
This demo shows how to use bm::set_value_kleene and bm::get_value_kleene functions to set values into...
Definition: bv3vlogic.cpp:90
static void PrintKleeneVector(const bm::bvector<> &bv_v, const bm::bvector<> &bv_null)
Print 3-value vector.
Definition: bv3vlogic.cpp:55
int main(void)
Definition: bv3vlogic.cpp:284
static void GenerateDemoVector(bm::bvector<> &bv_v, bm::bvector<> &bv_null)
Generate Kleene vector (as two bit-vectors)
Definition: bv3vlogic.cpp:164
static void Set3VL_InvertDemo()
Demo for 3-value logic (Kleene) NOT.
Definition: bv3vlogic.cpp:185
Output iterator iterator designed to set "ON" bits based on input sequence of integers.
Definition: bm.h:465
Constant iterator designed to enumerate "ON" bits.
Definition: bm.h:603
bool valid() const BMNOEXCEPT
Checks if iterator is still valid.
Definition: bm.h:283
Bitvector Bit-vector container with runtime compression of bits.
Definition: bm.h:115
bool test(size_type n) const BMNOEXCEPT
returns true if bit n is set and false is bit n is 0.
Definition: bm.h:1480
bool equal(const bvector< Alloc > &bvect) const BMNOEXCEPT
Equal comparison with an agr bit-vector.
Definition: bm.h:1995
void optimize(bm::word_t *temp_block=0, optmode opt_mode=opt_compress, statistics *stat=0)
Optimize memory bitvector's memory allocation.
Definition: bm.h:3600
insert_iterator inserter()
Definition: bm.h:1265
enumerator first() const
Returns enumerator pointing on the first non-zero bit.
Definition: bm.h:1849
void invert_kleene(BV &bv_value, const BV &bv_null)
Kleene NEG operation.
Definition: bm3vl.h:135
void init_kleene(BV &bv_value, const BV &bv_null)
Initialized the value bit-vector so that it always returns 0 (false) for the unknown.
Definition: bm3vl.h:54
void and_kleene(BV &bv_value1, BV &bv_null1, const BV &bv_value2, const BV &bv_null2)
Kleene AND(vect1, vect2) (vect1 &= vect2) 0 AND Unk = 0 (known)
Definition: bm3vl.h:213
void set_value_kleene(BV &bv_value, BV &bv_null, typename BV::size_type idx, int val)
Set Kleene logic value based on value and known vectors.
Definition: bm3vl.h:96
int get_value_kleene(const BV &bv_value, const BV &bv_null, typename BV::size_type idx) BMNOEXCEPT
Return Kleene logic value based on value and known vectors.
Definition: bm3vl.h:70
void or_kleene(BV &bv_value1, BV &bv_null1, const BV &bv_value2, const BV &bv_null2)
Kleene OR(vect1, vect2) (vect1 |= vect2) 1 OR Unk = 1 (known)
Definition: bm3vl.h:151