Substitution¶
Capture-free substitution and telescope instantiation.
substitution
¶
Capture-free substitution and telescope instantiation for QIEC.
StaticSubstitution
dataclass
¶
StaticSubstitution(types: tuple[tuple[str, TypeExpr], ...] = (), indices: tuple[tuple[str, IndexTerm], ...] = (), effects: tuple[tuple[str, EffectRef | EffectVariable], ...] = ())
A deterministic substitution split by static namespace.
| PARAMETER | DESCRIPTION |
|---|---|
types
|
Bindings from type-variable names to types.
TYPE:
|
indices
|
Bindings from index-variable names to index terms.
TYPE:
|
effects
|
Bindings from effect-variable names to interface applications or other effect variables.
TYPE:
|
__post_init__
¶
Reject a substitution that binds one name twice.
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If a name repeats within a namespace. Two bindings for one name would make the result depend on lookup order. |
Source code in src/quivers/qiec/substitution.py
type
¶
type(name: str) -> TypeExpr | None
What a type binder of this name is bound to.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
The binder name.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
TypeExpr or None
|
The bound type, or None when this substitution says nothing about the name, in which case the variable stands. |
Source code in src/quivers/qiec/substitution.py
index
¶
index(name: str) -> IndexTerm | None
What an index binder of this name is bound to.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
The binder name.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
IndexTerm or None
|
The bound index, or None when the name is unbound here. |
Source code in src/quivers/qiec/substitution.py
effect
¶
effect(name: str) -> EffectRef | EffectVariable | None
What an effect binder of this name is bound to.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
The binder name.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EffectRef or EffectVariable or None
|
The bound interface application or effect variable, or None when the name is unbound here. |
Source code in src/quivers/qiec/substitution.py
instantiate_telescope
¶
instantiate_telescope(telescope: Telescope, arguments: tuple[StaticArgument, ...]) -> StaticSubstitution
Kind-check static arguments and construct their substitution.
| PARAMETER | DESCRIPTION |
|---|---|
telescope
|
The binders to instantiate, in order. Later binders may depend on earlier ones, so the arguments are checked left to right with the substitution built so far already applied.
TYPE:
|
arguments
|
One argument per binder.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
StaticSubstitution
|
The substitution carrying each binder to its argument. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If an argument is of the wrong static class for its binder. |
ValueError
|
If the counts differ, or an argument is of the wrong kind or index sort. |
Source code in src/quivers/qiec/substitution.py
substitute_index
¶
substitute_index(term: IndexTerm, substitution: StaticSubstitution) -> IndexTerm
Substitute into an index term.
| PARAMETER | DESCRIPTION |
|---|---|
term
|
The index to rewrite.
TYPE:
|
substitution
|
The bindings to apply.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
IndexTerm
|
The rewritten index. A variable carrying an identity is rigid and is returned unchanged, which is what keeps a branch's skolem from being captured by a like-named declaration binder. |
Source code in src/quivers/qiec/substitution.py
substitute_effect
¶
substitute_effect(effect: EffectRef, substitution: StaticSubstitution) -> EffectRef
Substitute into an interface application's static arguments.
| PARAMETER | DESCRIPTION |
|---|---|
effect
|
The application to rewrite.
TYPE:
|
substitution
|
The bindings to apply.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EffectRef
|
The application with its arguments rewritten. The declaration's identity and name are unchanged, since substitution instantiates an interface rather than selecting a different one. |
Source code in src/quivers/qiec/substitution.py
substitute_plate
¶
substitute_plate(plate: PlateShape, substitution: StaticSubstitution) -> PlateShape
Substitute static variables in a plate's axis sizes.
| PARAMETER | DESCRIPTION |
|---|---|
plate
|
The plate.
TYPE:
|
substitution
|
The static substitution.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
PlateShape
|
The plate with every axis size substituted. |
Source code in src/quivers/qiec/substitution.py
substitute_type
¶
substitute_type(type_: TypeExpr, substitution: StaticSubstitution) -> TypeExpr
Substitute into a type expression.
| PARAMETER | DESCRIPTION |
|---|---|
type_
|
The type to rewrite.
TYPE:
|
substitution
|
The bindings to apply.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
TypeExpr
|
The rewritten type. As with indices, a variable carrying an identity is rigid and survives unchanged. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the expression is of an unknown class. |
Source code in src/quivers/qiec/substitution.py
substitute_static
¶
substitute_static(term: StaticArgument, substitution: StaticSubstitution) -> StaticArgument
Substitute into a static argument of any namespace.
| PARAMETER | DESCRIPTION |
|---|---|
term
|
A type, index, or effect argument.
TYPE:
|
substitution
|
The bindings to apply.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
StaticArgument
|
The rewritten argument, dispatched to the namespace it belongs to. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the term is of an unknown class. |
Source code in src/quivers/qiec/substitution.py
substitute_row
¶
substitute_row(row: EffectRow, substitution: StaticSubstitution) -> EffectRow
Substitute into every interface application in an effect row.
| PARAMETER | DESCRIPTION |
|---|---|
row
|
The row to rewrite.
TYPE:
|
substitution
|
The bindings to apply.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EffectRow
|
The row with each entry's interface rewritten. Instance identities and the open tail are untouched: this substitutes static arguments, and a row variable is solved by unification rather than by this substitution. |
Source code in src/quivers/qiec/substitution.py
instantiate_operation
¶
instantiate_operation(operation: OperationDef, arguments: tuple[StaticArgument, ...], outer: StaticSubstitution = StaticSubstitution()) -> tuple[tuple[TypeExpr, ...], TypeExpr]
Instantiate an operation's signature at a request site.
| PARAMETER | DESCRIPTION |
|---|---|
operation
|
The declared operation.
TYPE:
|
arguments
|
Static arguments for the operation's own telescope.
TYPE:
|
outer
|
Bindings already in force from the interface's telescope. These come first, so an operation binder of the same name shadows the interface's, which is the scoping a reader expects.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple[tuple[TypeExpr, ...], TypeExpr]
|
The instantiated parameter types and result type. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If an argument is of the wrong static class for its binder. |
ValueError
|
If the argument count is wrong, or an argument is ill-kinded. |
Source code in src/quivers/qiec/substitution.py
substitute_evidence
¶
substitute_evidence(evidence: EqualityEvidence, substitution: StaticSubstitution) -> EqualityEvidence
Substitute into the equality an evidence term states.
| PARAMETER | DESCRIPTION |
|---|---|
evidence
|
The evidence to rewrite.
TYPE:
|
substitution
|
The static bindings to apply.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EqualityEvidence
|
Evidence of the same class stating the substituted equality. A branch given keeps its identity, since substituting into what it proves does not make it a different piece of evidence. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the evidence is of an unknown class. |
Source code in src/quivers/qiec/substitution.py
substitute_value
¶
substitute_value(value: Value, substitution: StaticSubstitution) -> Value
Substitute static arguments throughout a value term.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
The value to rewrite.
TYPE:
|
substitution
|
The static bindings to apply.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Value
|
The value with every type, index, and effect position substituted. Value-level structure is untouched: this rewrites the static layer, not the data. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the value is of an unknown class. |
Source code in src/quivers/qiec/substitution.py
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 | |
substitute_request
¶
substitute_request(request: EffectRequest, substitution: StaticSubstitution) -> EffectRequest
Substitute static arguments throughout an effect request.
| PARAMETER | DESCRIPTION |
|---|---|
request
|
The request to rewrite.
TYPE:
|
substitution
|
The static bindings to apply.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EffectRequest
|
The request against the substituted interface application, with its own static and value arguments and result type rewritten. The instance, the operation, and the site are identities and do not move. |
Source code in src/quivers/qiec/substitution.py
substitute_computation
¶
substitute_computation(computation: Computation, substitution: StaticSubstitution) -> Computation
Substitute static arguments throughout a computation.
Capture cannot occur, and the reason is structural rather than a
freshening pass. A substitution binds declaration binders, which
carry no identity and are matched by name. Every binder a computation
introduces is rigid: a case branch's skolems are built with derived
StaticVariableIds, and substitute_type and substitute_static
return a variable carrying an identity unchanged. So a branch's own
binders are invisible to substitution while references to an
enclosing declaration binder inside that branch are rewritten, which
is exactly the capture-avoiding behavior.
| PARAMETER | DESCRIPTION |
|---|---|
computation
|
The computation to rewrite.
TYPE:
|
substitution
|
The static bindings to apply.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Computation
|
The computation with every static position substituted. Identities are preserved throughout: a call still names the same callee, a handle the same handler, and an allocation the same instance. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the computation, or a term nested in it, is of an unknown class. |
Source code in src/quivers/qiec/substitution.py
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 | |