| | 354 | def __invert__(self): |
| | 355 | """ |
| | 356 | Return the complement Boolean function of `self`. |
| | 357 | |
| | 358 | EXAMPLE:: |
| | 359 | |
| | 360 | sage: from sage.crypto.boolean_function import BooleanFunction |
| | 361 | sage: B=BooleanFunction([0, 1, 1, 0, 1, 0, 0, 0]) |
| | 362 | sage: (~B).truth_table(format='int') |
| | 363 | (1, 0, 0, 1, 0, 1, 1, 1) |
| | 364 | """ |
| | 365 | cdef BooleanFunction res=BooleanFunction(self.nvariables()) |
| | 366 | bitset_complement(res._truth_table, self._truth_table) |
| | 367 | return res |
| | 368 | |
| | 369 | def __iadd__(self, BooleanFunction other): |
| | 370 | """ |
| | 371 | Inplace add `other` to `self`. |
| | 372 | |
| | 373 | EXAMPLE:: |
| | 374 | |
| | 375 | sage: from sage.crypto.boolean_function import BooleanFunction |
| | 376 | sage: A=BooleanFunction([0, 1, 0, 1, 1, 0, 0, 1]) |
| | 377 | sage: A += BooleanFunction([0, 1, 1, 0, 1, 0, 0, 0]) |
| | 378 | sage: A.truth_table(format='int') |
| | 379 | (0, 0, 1, 1, 0, 0, 0, 1) |
| | 380 | |
| | 381 | TESTS:: |
| | 382 | |
| | 383 | sage: A+=BooleanFunction([0,1]) |
| | 384 | Traceback (most recent call last): |
| | 385 | ... |
| | 386 | ValueError: the two Boolean functions must have the same number of variables |
| | 387 | """ |
| | 388 | if (self._nvariables != other._nvariables): |
| | 389 | raise ValueError("the two Boolean functions must have the same number of variables") |
| | 390 | bitset_xor(self._truth_table, self._truth_table, other._truth_table) |
| | 391 | return self |
| | 392 | |
| | 393 | def __add__(self, other): |
| | 394 | """ |
| | 395 | Return the element wise sum of `self`and `other` which must have the same number of variables. |
| | 396 | |
| | 397 | EXAMPLE:: |
| | 398 | |
| | 399 | sage: from sage.crypto.boolean_function import BooleanFunction |
| | 400 | sage: A=BooleanFunction([0, 1, 0, 1, 1, 0, 0, 1]) |
| | 401 | sage: B=BooleanFunction([0, 1, 1, 0, 1, 0, 0, 0]) |
| | 402 | sage: (A+B).truth_table(format='int') |
| | 403 | (0, 0, 1, 1, 0, 0, 0, 1) |
| | 404 | |
| | 405 | it also corresponds to the addition of algebraic normal forms:: |
| | 406 | |
| | 407 | sage: S = A.algebraic_normal_form() + B.algebraic_normal_form() |
| | 408 | sage: (A+B).algebraic_normal_form() == S |
| | 409 | True |
| | 410 | |
| | 411 | TESTS:: |
| | 412 | |
| | 413 | sage: A+BooleanFunction([0,1]) |
| | 414 | Traceback (most recent call last): |
| | 415 | ... |
| | 416 | ValueError: the two Boolean functions must have the same number of variables |
| | 417 | """ |
| | 418 | cdef BooleanFunction res=BooleanFunction(self) |
| | 419 | res += other |
| | 420 | return res |
| | 421 | |
| | 422 | def __imul__(self, BooleanFunction other): |
| | 423 | """ |
| | 424 | Inplace multiply `other` to `self`. |
| | 425 | |
| | 426 | EXAMPLE:: |
| | 427 | |
| | 428 | sage: from sage.crypto.boolean_function import BooleanFunction |
| | 429 | sage: A=BooleanFunction([0, 1, 0, 1, 1, 0, 0, 1]) |
| | 430 | sage: A += BooleanFunction([0, 1, 1, 0, 1, 0, 0, 0]) |
| | 431 | sage: A.truth_table(format='int') |
| | 432 | (0, 0, 1, 1, 0, 0, 0, 1) |
| | 433 | |
| | 434 | TESTS:: |
| | 435 | |
| | 436 | sage: A*=BooleanFunction([0,1]) |
| | 437 | Traceback (most recent call last): |
| | 438 | ... |
| | 439 | ValueError: the two Boolean functions must have the same number of variables |
| | 440 | """ |
| | 441 | if (self._nvariables != other._nvariables): |
| | 442 | raise ValueError("the two Boolean functions must have the same number of variables") |
| | 443 | bitset_and(self._truth_table, self._truth_table, other._truth_table) |
| | 444 | return self |
| | 445 | |
| | 446 | def __mul__(self, other): |
| | 447 | """ |
| | 448 | Return the elementwise multiplication of `self`and `other` which must have the same number of variables. |
| | 449 | |
| | 450 | EXAMPLE:: |
| | 451 | |
| | 452 | sage: from sage.crypto.boolean_function import BooleanFunction |
| | 453 | sage: A=BooleanFunction([0, 1, 0, 1, 1, 0, 0, 1]) |
| | 454 | sage: B=BooleanFunction([0, 1, 1, 0, 1, 0, 0, 0]) |
| | 455 | sage: (A*B).truth_table(format='int') |
| | 456 | (0, 1, 0, 0, 1, 0, 0, 0) |
| | 457 | |
| | 458 | it also corresponds to the multiplication of algebraic normal forms:: |
| | 459 | |
| | 460 | sage: P = A.algebraic_normal_form() * B.algebraic_normal_form() |
| | 461 | sage: (A*B).algebraic_normal_form() == P |
| | 462 | True |
| | 463 | |
| | 464 | TESTS:: |
| | 465 | |
| | 466 | sage: A*BooleanFunction([0,1]) |
| | 467 | Traceback (most recent call last): |
| | 468 | ... |
| | 469 | ValueError: the two Boolean functions must have the same number of variables |
| | 470 | """ |
| | 471 | cdef BooleanFunction res=BooleanFunction(self) |
| | 472 | res *= other |
| | 473 | return res |
| | 474 | |
| | 475 | def __or__(BooleanFunction self, BooleanFunction other): |
| | 476 | """ |
| | 477 | Return the concatenation of `self` and `other` which must have the same number of variables. |
| | 478 | |
| | 479 | EXAMPLE:: |
| | 480 | |
| | 481 | sage: from sage.crypto.boolean_function import BooleanFunction |
| | 482 | sage: A=BooleanFunction([0, 1, 0, 1]) |
| | 483 | sage: B=BooleanFunction([0, 1, 1, 0]) |
| | 484 | sage: (A|B).truth_table(format='int') |
| | 485 | (0, 1, 0, 1, 0, 1, 1, 0) |
| | 486 | |
| | 487 | sage: C = A.truth_table() + B.truth_table() |
| | 488 | sage: (A|B).truth_table(format='int') == C |
| | 489 | True |
| | 490 | |
| | 491 | TESTS:: |
| | 492 | |
| | 493 | sage: A|BooleanFunction([0,1]) |
| | 494 | Traceback (most recent call last): |
| | 495 | ... |
| | 496 | ValueError: the two Boolean functions must have the same number of variables |
| | 497 | """ |
| | 498 | if (self._nvariables != other.nvariables()): |
| | 499 | raise ValueError("the two Boolean functions must have the same number of variables") |
| | 500 | |
| | 501 | cdef BooleanFunction res=BooleanFunction(self.nvariables()+1) |
| | 502 | |
| | 503 | nb_limbs = self._truth_table.limbs |
| | 504 | if nb_limbs == 1: |
| | 505 | L = len(self) |
| | 506 | for i in range(L): |
| | 507 | res[i ]=self[i] |
| | 508 | res[i+L]=other[i] |
| | 509 | return res |
| | 510 | |
| | 511 | memcpy(res._truth_table.bits , self._truth_table.bits, nb_limbs * sizeof(unsigned long)) |
| | 512 | memcpy(&(res._truth_table.bits[nb_limbs]),other._truth_table.bits, nb_limbs * sizeof(unsigned long)) |
| | 513 | |
| | 514 | return res |
| | 515 | |
| | 516 | |