OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace commits / 3b95200

Add bool printer utility
3b952008b85bf748cf3dbccb21644f1a4b0447c8
by Linas Vepštas <linasvepstas@gmail.com> · 2026-01-23T19:19:27.000Z

Changed files (2) +80 -63

opencog/atoms/value/BoolValue.cc +78 -63
……@@ -166,6 +166,72 @@ bool BoolValue::operator==(const Value& other) const
166166// and even then, storing super-long bitstrings should probably
167167// be done in some way that is more efficient. For now, this is
168168// a stop-gap for experimentation. As always ...
169std::string BoolValue::raw_hex_string() const
170{
171 // Print in hexadecimal
172 std::string rv = " #x";
173
174 // The native storage format used above is big endian, in that
175 // bit zero is the left-most bit, bit one is to the right of that,
176 // and so on. This is easier to print than little-endian (which
177 // would force us to bit swap) but still presents some challenge.
178 size_t word_count = words_needed(_bit_count);
179
180 // Print full 16 hex digits if we're lucky.
181 int bit_align = _bit_count % 64;
182 if (0 == bit_align)
183 {
184 for (size_t w = 0; w < word_count; w++) {
185 uint64_t word = _packed_bits[w];
186 char buf[17];
187 snprintf(buf, sizeof(buf), "%016lx", word);
188 rv += buf;
189 }
190 rv += ")";
191 return rv;
192 }
193
194 // First word to be padded by zeros, as needed.
195 uint64_t word = _packed_bits[0];
196 uint64_t mask = (1ULL << (64 - bit_align)) - 1;
197 uint64_t carry = (word & mask) << bit_align;
198 word >>= (64 - bit_align);
199 int width = (bit_align + 3) >> 2;
200 char buf[17];
201 snprintf(buf, sizeof(buf), "%0*lx", width, word);
202 rv += buf;
203
204 // Are we done yet?
205 if (1 == word_count)
206 {
207 rv += ")";
208 return rv;
209 }
210
211 // Middle words are spliced from low bits of previous
212 // and high bits of current.
213 for (size_t w = 1; w < word_count - 1; w++)
214 {
215 uint64_t word = _packed_bits[w];
216 uint64_t mask = (1ULL << (64 - bit_align)) - 1;
217 uint64_t rbits = (word & mask) << bit_align;
218 word >>= (64 - bit_align);
219 word = word | carry;
220 carry = rbits;
221 snprintf(buf, sizeof(buf), "%016lx", word);
222 rv += buf;
223 }
224
225 // Last word handling
226 word = _packed_bits[word_count - 1];
227 word >>= (64 - bit_align);
228 word = word | carry;
229 snprintf(buf, sizeof(buf), "%lx", word);
230 rv += buf;
231
232 return rv;
233}
234
169235std::string BoolValue::to_string(const std::string& indent, Type t) const
170236{
171237 std::string rv = indent + "(" + nameserver().getTypeName(t);
……@@ -179,76 +245,25 @@ std::string BoolValue::to_string(const std::string& indent, Type t) const
179245 if (get_bit(i)) rv += " 1";
180246 else rv += " 0";
181247 }
182 rv += ")";
183 return rv;
184248 }
185
186 // For longer bitstrings, print in hexadecimal
187 rv += " #x";
188
189 // The native storage format used above is big endian, in that
190 // bit zero is the left-most bit, bit one is to the right of that,
191 // and so on. This is easier to print than little-endian (which
192 // would force us to bit swap) but still presents some challenge.
193 size_t word_count = words_needed(_bit_count);
194
195 // Print full 16 hex digits if we're lucky.
196 int bit_align = _bit_count % 64;
197 if (0 == bit_align)
198 {
199 for (size_t w = 0; w < word_count; w++) {
200 uint64_t word = _packed_bits[w];
201 char buf[17];
202 snprintf(buf, sizeof(buf), "%016lx", word);
203 rv += buf;
204 }
205 rv += ")";
206 return rv;
207 }
208
209 // First word to be padded by zeros, as needed.
210 uint64_t word = _packed_bits[0];
211 uint64_t mask = (1ULL << (64 - bit_align)) - 1;
212 uint64_t carry = (word & mask) << bit_align;
213 word >>= (64 - bit_align);
214 int width = (bit_align + 3) >> 2;
215 char buf[17];
216 snprintf(buf, sizeof(buf), "%0*lx", width, word);
217 rv += buf;
218
219 // Are we done yet?
220 if (1 == word_count)
221 {
222 rv += ")";
223 return rv;
224 }
225
226 // Middle words are spliced from low bits of previous
227 // and high bits of current.
228 for (size_t w = 1; w < word_count - 1; w++)
229 {
230 uint64_t word = _packed_bits[w];
231 uint64_t mask = (1ULL << (64 - bit_align)) - 1;
232 uint64_t rbits = (word & mask) << bit_align;
233 word >>= (64 - bit_align);
234 word = word | carry;
235 carry = rbits;
236 snprintf(buf, sizeof(buf), "%016lx", word);
237 rv += buf;
238 }
239
240 // Last word handling
241 word = _packed_bits[word_count - 1];
242 word >>= (64 - bit_align);
243 word = word | carry;
244 snprintf(buf, sizeof(buf), "%lx", word);
245 rv += buf;
249 else
250 rv += raw_hex_string();
246251 });
247252
248253 rv += ")";
249254 return rv;
250255}
251256
257std::string BoolValue::hex_string() const
258{
259 std::string rv;
260 SAFE_UPDATE(rv,
261 {
262 rv = raw_hex_string();
263 });
264 return rv;
265}
266
252267// ==============================================================
253268// Optimized packed boolean operations (static/internal use only)
254269
opencog/atoms/value/BoolValue.h +2 -0
……@@ -56,6 +56,7 @@ protected:
5656 void set_bit(size_t index, bool value) const;
5757 void pack_vector(const std::vector<bool>&);
5858 std::vector<bool> unpack_vector() const;
59 std::string raw_hex_string() const;
5960
6061 BoolValue(Type t, const std::vector<bool>&);
6162 BoolValue(Type t, std::vector<uint64_t>&&);
……@@ -72,6 +73,7 @@ public:
7273 /** Returns a string representation of the value. */
7374 virtual std::string to_string(const std::string& indent = "") const;
7475 std::string to_string(const std::string& indent, Type) const;
76 std::string hex_string() const;
7577
7678 /** Returns true if two values are equal. */
7779 virtual bool operator==(const Value&) const;