|
409 | 409 | "cell_type": "markdown", |
410 | 410 | "metadata": {}, |
411 | 411 | "source": [ |
412 | | - "\n", |
413 | | - "\n", |
414 | | - "\n", |
415 | | - "\n", |
416 | 412 | "\n", |
417 | 413 | "(* ================================================================= *)\n", |
418 | | - "(** ** Example: Permutations *)\n", |
| 414 | + "# Example: Permutations *)\n", |
419 | 415 | "\n", |
420 | 416 | "(** The familiar mathematical concept of _permutation_ also has an\n", |
421 | 417 | " elegant formulation as an inductive relation. For simplicity,\n", |
|
453 | 449 | " - apply perm3_swap12.\n", |
454 | 450 | " - apply perm3_swap23. Qed.\n", |
455 | 451 | "\n", |
456 | | - "(* ================================================================= *)\n", |
| 452 | + "(* ================================================================= *)" |
| 453 | + ] |
| 454 | + }, |
| 455 | + { |
| 456 | + "cell_type": "code", |
| 457 | + "execution_count": null, |
| 458 | + "metadata": {}, |
| 459 | + "outputs": [ |
| 460 | + { |
| 461 | + "name": "stdout", |
| 462 | + "output_type": "stream", |
| 463 | + "text": [ |
| 464 | + "WARNING: Redefining function perm3 from |- ForAll([perm3!150, seq!151, seq!152],\n", |
| 465 | + " perm3(perm3!150, seq!151, seq!152) ==\n", |
| 466 | + " If(is(perm3_swap12, perm3!150),\n", |
| 467 | + " And(Nth(seq!151, 0) == Nth(seq!152, 1),\n", |
| 468 | + " Nth(seq!151, 1) == Nth(seq!152, 0),\n", |
| 469 | + " Nth(seq!151, 2) == Nth(seq!152, 2)),\n", |
| 470 | + " If(is(perm3_swap23, perm3!150),\n", |
| 471 | + " And(Nth(seq!151, 0) == Nth(seq!152, 0),\n", |
| 472 | + " Nth(seq!151, 1) == Nth(seq!152, 2),\n", |
| 473 | + " Nth(seq!151, 2) == Nth(seq!152, 1)),\n", |
| 474 | + " If(is(perm3_trans, perm3!150),\n", |
| 475 | + " And(perm3(ev1(perm3!150),\n", |
| 476 | + " seq!151,\n", |
| 477 | + " y(perm3!150)),\n", |
| 478 | + " perm3(ev2(perm3!150),\n", |
| 479 | + " y(perm3!150),\n", |
| 480 | + " seq!152)),\n", |
| 481 | + " unreachable!153)))) to ForAll([perm3!154, seq!155, seq!156],\n", |
| 482 | + " perm3(perm3!154, seq!155, seq!156) ==\n", |
| 483 | + " If(is(perm3_swap12, perm3!154),\n", |
| 484 | + " And(Nth(seq!155, 0) == Nth(seq!156, 1),\n", |
| 485 | + " Nth(seq!155, 1) == Nth(seq!156, 0),\n", |
| 486 | + " Nth(seq!155, 2) == Nth(seq!156, 2)),\n", |
| 487 | + " If(is(perm3_swap23, perm3!154),\n", |
| 488 | + " And(Nth(seq!155, 0) == Nth(seq!156, 0),\n", |
| 489 | + " Nth(seq!155, 1) == Nth(seq!156, 2),\n", |
| 490 | + " Nth(seq!155, 2) == Nth(seq!156, 1)),\n", |
| 491 | + " If(is(perm3_trans, perm3!154),\n", |
| 492 | + " And(perm3(ev1(perm3!154),\n", |
| 493 | + " seq!155,\n", |
| 494 | + " y(perm3!154)),\n", |
| 495 | + " perm3(ev2(perm3!154),\n", |
| 496 | + " y(perm3!154),\n", |
| 497 | + " seq!156)),\n", |
| 498 | + " unreachable!157))))\n", |
| 499 | + "[|- ForAll([perm3!154, seq!155, seq!156],\n", |
| 500 | + " perm3(perm3!154, seq!155, seq!156) ==\n", |
| 501 | + " If(is(perm3_swap12, perm3!154),\n", |
| 502 | + " And(Nth(seq!155, 0) == Nth(seq!156, 1),\n", |
| 503 | + " Nth(seq!155, 1) == Nth(seq!156, 0),\n", |
| 504 | + " Nth(seq!155, 2) == Nth(seq!156, 2)),\n", |
| 505 | + " If(is(perm3_swap23, perm3!154),\n", |
| 506 | + " And(Nth(seq!155, 0) == Nth(seq!156, 0),\n", |
| 507 | + " Nth(seq!155, 1) == Nth(seq!156, 2),\n", |
| 508 | + " Nth(seq!155, 2) == Nth(seq!156, 1)),\n", |
| 509 | + " If(is(perm3_trans, perm3!154),\n", |
| 510 | + " And(perm3(ev1(perm3!154),\n", |
| 511 | + " seq!155,\n", |
| 512 | + " y(perm3!154)),\n", |
| 513 | + " perm3(ev2(perm3!154),\n", |
| 514 | + " y(perm3!154),\n", |
| 515 | + " seq!156)),\n", |
| 516 | + " unreachable!157)))), |- Implies(perm3(perm3_trans(perm3_swap12,\n", |
| 517 | + " perm3_swap23,\n", |
| 518 | + " Concat(Unit(2),\n", |
| 519 | + " Concat(Unit(1), Unit(3)))),\n", |
| 520 | + " Concat(Unit(1), Concat(Unit(2), Unit(3))),\n", |
| 521 | + " Concat(Unit(2), Concat(Unit(3), Unit(1)))),\n", |
| 522 | + " Exists(ev,\n", |
| 523 | + " perm3(ev,\n", |
| 524 | + " Concat(Unit(1),\n", |
| 525 | + " Concat(Unit(2), Unit(3))),\n", |
| 526 | + " Concat(Unit(2),\n", |
| 527 | + " Concat(Unit(3), Unit(1))))))]\n" |
| 528 | + ] |
| 529 | + }, |
| 530 | + { |
| 531 | + "data": { |
| 532 | + "text/html": [ |
| 533 | + "⊦Exists(ev,\n", |
| 534 | + " perm3(ev,\n", |
| 535 | + " Concat(Unit(1), Concat(Unit(2), Unit(3))),\n", |
| 536 | + " Concat(Unit(2), Concat(Unit(3), Unit(1)))))" |
| 537 | + ], |
| 538 | + "text/plain": [ |
| 539 | + "|- Exists(ev,\n", |
| 540 | + " perm3(ev,\n", |
| 541 | + " Concat(Unit(1), Concat(Unit(2), Unit(3))),\n", |
| 542 | + " Concat(Unit(2), Concat(Unit(3), Unit(1)))))" |
| 543 | + ] |
| 544 | + }, |
| 545 | + "execution_count": 2, |
| 546 | + "metadata": {}, |
| 547 | + "output_type": "execute_result" |
| 548 | + } |
| 549 | + ], |
| 550 | + "source": [ |
| 551 | + "from kdrag.all import *\n", |
| 552 | + "\n", |
| 553 | + "Perm3 = kd.notation.InductiveRel(\"Perm3\", smt.SeqSort(smt.IntSort()), smt.SeqSort(smt.IntSort()), admit=True)\n", |
| 554 | + "Perm3.declare(\"perm3_swap12\", pred= lambda s1,s2: smt.And(s1[0] == s2[1], s1[1] == s2[0], s1[2] == s2[2]))\n", |
| 555 | + "Perm3.declare(\"perm3_swap23\", pred= lambda s1,s2: smt.And(s1[0] == s2[0], s1[1] == s2[2], s1[2] == s2[1]))\n", |
| 556 | + "Perm3.declare(\"perm3_trans\", (\"ev1\", Perm3), (\"ev2\", Perm3), (\"y\", smt.SeqSort(smt.IntSort())), \n", |
| 557 | + " pred=lambda ev1,ev2,y,s1,s2: ev1.rel(s1,y) & ev2.rel(y,s2))\n", |
| 558 | + "Perm3 = Perm3.create() \n", |
| 559 | + "Perm3.rel.defn\n", |
| 560 | + "\n", |
| 561 | + "ev = smt.Const(\"ev\", Perm3)\n", |
| 562 | + "\n", |
| 563 | + "def seq(*args):\n", |
| 564 | + " return smt.Concat(*[smt.Unit(smt.py2expr(arg)) for arg in args])\n", |
| 565 | + "\n", |
| 566 | + "l = kd.Lemma(smt.Exists([ev], ev.rel(seq(1,2,3), seq(2,3,1))))\n", |
| 567 | + "l.exists(Perm3.perm3_trans(Perm3.perm3_swap12, Perm3.perm3_swap23, seq(2,1,3)))\n", |
| 568 | + "#l.auto(by=Perm3.rel.defn)\n", |
| 569 | + "#l.lemmas\n", |
| 570 | + "l.qed(by=[Perm3.rel.defn])\n", |
| 571 | + "\n", |
| 572 | + "# TODO: I need to implement unification to repliace their proof.\n" |
| 573 | + ] |
| 574 | + }, |
| 575 | + { |
| 576 | + "cell_type": "code", |
| 577 | + "execution_count": null, |
| 578 | + "metadata": {}, |
| 579 | + "outputs": [ |
| 580 | + { |
| 581 | + "ename": "LemmaError", |
| 582 | + "evalue": "('In by reasons:', [|- ForAll([perm3!150, seq!151, seq!152],\n perm3(perm3!150, seq!151, seq!152) ==\n If(is(perm3_swap12, perm3!150),\n And(Nth(seq!151, 0) == Nth(seq!152, 1),\n Nth(seq!151, 1) == Nth(seq!152, 0),\n Nth(seq!151, 2) == Nth(seq!152, 2)),\n If(is(perm3_swap23, perm3!150),\n And(Nth(seq!151, 0) == Nth(seq!152, 0),\n Nth(seq!151, 1) == Nth(seq!152, 2),\n Nth(seq!151, 2) == Nth(seq!152, 1)),\n If(is(perm3_trans, perm3!150),\n And(perm3(ev1(perm3!150),\n seq!151,\n y(perm3!150)),\n perm3(ev2(perm3!150),\n y(perm3!150),\n seq!152)),\n unreachable!153))))], 'is not a Proof object')", |
| 583 | + "output_type": "error", |
| 584 | + "traceback": [ |
| 585 | + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", |
| 586 | + "\u001b[0;31mLemmaError\u001b[0m Traceback (most recent call last)", |
| 587 | + "Cell \u001b[0;32mIn[2], line 9\u001b[0m\n\u001b[1;32m 7\u001b[0m l\u001b[38;5;241m.\u001b[39mexists(Perm3\u001b[38;5;241m.\u001b[39mperm3_trans(Perm3\u001b[38;5;241m.\u001b[39mperm3_swap12, Perm3\u001b[38;5;241m.\u001b[39mperm3_swap23, seq(\u001b[38;5;241m2\u001b[39m,\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m3\u001b[39m)))\n\u001b[1;32m 8\u001b[0m \u001b[38;5;66;03m#l.auto(by=Perm3.rel.defn)\u001b[39;00m\n\u001b[0;32m----> 9\u001b[0m \u001b[43ml\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mqed\u001b[49m\u001b[43m(\u001b[49m\u001b[43mby\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m[\u001b[49m\u001b[43mPerm3\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdefn\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n", |
| 588 | + "File \u001b[0;32m~/Documents/python/knuckledragger/kdrag/tactics.py:767\u001b[0m, in \u001b[0;36mLemma.qed\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 765\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 766\u001b[0m kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mby\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlemmas\n\u001b[0;32m--> 767\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mkd\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mkernel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlemma\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mthm\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", |
| 589 | + "File \u001b[0;32m~/Documents/python/knuckledragger/kdrag/kernel.py:80\u001b[0m, in \u001b[0;36mlemma\u001b[0;34m(thm, by, admit, timeout, dump, solver)\u001b[0m\n\u001b[1;32m 78\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m by:\n\u001b[1;32m 79\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(p, __Proof):\n\u001b[0;32m---> 80\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m LemmaError(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIn by reasons:\u001b[39m\u001b[38;5;124m\"\u001b[39m, p, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mis not a Proof object\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 81\u001b[0m s\u001b[38;5;241m.\u001b[39madd(p\u001b[38;5;241m.\u001b[39mthm)\n\u001b[1;32m 82\u001b[0m s\u001b[38;5;241m.\u001b[39madd(smt\u001b[38;5;241m.\u001b[39mNot(thm))\n", |
| 590 | + "\u001b[0;31mLemmaError\u001b[0m: ('In by reasons:', [|- ForAll([perm3!150, seq!151, seq!152],\n perm3(perm3!150, seq!151, seq!152) ==\n If(is(perm3_swap12, perm3!150),\n And(Nth(seq!151, 0) == Nth(seq!152, 1),\n Nth(seq!151, 1) == Nth(seq!152, 0),\n Nth(seq!151, 2) == Nth(seq!152, 2)),\n If(is(perm3_swap23, perm3!150),\n And(Nth(seq!151, 0) == Nth(seq!152, 0),\n Nth(seq!151, 1) == Nth(seq!152, 2),\n Nth(seq!151, 2) == Nth(seq!152, 1)),\n If(is(perm3_trans, perm3!150),\n And(perm3(ev1(perm3!150),\n seq!151,\n y(perm3!150)),\n perm3(ev2(perm3!150),\n y(perm3!150),\n seq!152)),\n unreachable!153))))], 'is not a Proof object')" |
| 591 | + ] |
| 592 | + } |
| 593 | + ], |
| 594 | + "source": [] |
| 595 | + }, |
| 596 | + { |
| 597 | + "cell_type": "code", |
| 598 | + "execution_count": null, |
| 599 | + "metadata": {}, |
| 600 | + "outputs": [], |
| 601 | + "source": [ |
| 602 | + "#l.qed(by=Perm3.rel.defn)\n", |
| 603 | + "\"\"\"\n", |
| 604 | + "l.unfold(Perm3.rel)\n", |
| 605 | + "l.simp()\n", |
| 606 | + "l.split()\n", |
| 607 | + "\n", |
| 608 | + "l.unfold(Perm3.rel)\n", |
| 609 | + "l.simp()\n", |
| 610 | + "l.auto()\n", |
| 611 | + "\n", |
| 612 | + "l.auto(by=Perm3.rel.defn)\n", |
| 613 | + "l.qed()\n", |
| 614 | + "\"\"\"\n", |
| 615 | + "\n", |
| 616 | + "#l.auto(by=Perm3.rel.defn)" |
| 617 | + ] |
| 618 | + }, |
| 619 | + { |
| 620 | + "cell_type": "markdown", |
| 621 | + "metadata": {}, |
| 622 | + "source": [ |
| 623 | + "\n", |
| 624 | + "\n", |
| 625 | + "\n", |
| 626 | + "\n", |
| 627 | + "\n", |
457 | 628 | "(** ** Example: Evenness (yet again) *)\n", |
458 | 629 | "\n", |
459 | 630 | "(** We've already seen two ways of stating a proposition that a number\n", |
|
0 commit comments