@@ -1688,3 +1688,103 @@ Get the `IRStructure` associated with the system.
16881688function get_irstructure (sys:: System )
16891689 return get_irstructure_tlv (sys)[]:: IRStructure{SymReal}
16901690end
1691+
1692+ # Reversible transformation API
1693+
1694+ abstract type ReversibleTransformations end
1695+
1696+ """
1697+ $TYPEDSIGNATURES
1698+
1699+ Add `tf` to the list of reversible transformations applied to `sys`. Returns a modified
1700+ copy of `sys`. Reversible transformations must define [`reverse_transformation`](@ref).
1701+ They can also define several functions to determine when they are reversed. Transformations
1702+ are reversed in the reverse order of application.
1703+ """
1704+ function with_reversible_transformation (sys:: System , @nospecialize (tf))
1705+ prev_tfs = getmetadata (sys, ReversibleTransformations, nothing ):: Union{Nothing, Vector{Any}}
1706+ new_tfs:: Vector{Any} = if prev_tfs === nothing
1707+ []
1708+ else
1709+ copy (prev_tfs)
1710+ end
1711+ push! (new_tfs, tf)
1712+ return setmetadata (sys, ReversibleTransformations, new_tfs)
1713+ end
1714+
1715+ """
1716+ $TYPEDSIGNATURES
1717+
1718+ Filter the reversible transformations applied to `sys`. Return a new system with the
1719+ updated list of transformations.
1720+ """
1721+ function filter_reversible_transformations (fn:: F , sys:: System ) where {F}
1722+ prev_tfs = getmetadata (sys, ReversibleTransformations, []):: Union{Nothing, Vector{Any}}
1723+ new_tfs:: Vector{Any} = if prev_tfs === nothing
1724+ []
1725+ else
1726+ copy (prev_tfs)
1727+ end
1728+ filter! (fn, new_tfs)
1729+ return setmetadata (sys, ReversibleTransformations, new_tfs)
1730+ end
1731+
1732+ """
1733+ function reverse_transformation(sys::System, tf)
1734+
1735+ Reverse a reversible transformation ([`with_reversible_transformation`](@ref)) applied to `sys`.
1736+ """
1737+ function reverse_transformation end
1738+
1739+ """
1740+ $TYPEDSIGNATURES
1741+
1742+ Return a boolean indicating whether the transformation `tf` is reversed by default
1743+ when performing operations that require reversing such transformations. Defaults to
1744+ `true` for all transformations.
1745+ """
1746+ reverse_transformation_by_default (@nospecialize (tf)) = true
1747+
1748+ """
1749+ $TYPEDSIGNATURES
1750+
1751+ Return a boolean indicating whether the transformation `tf` is reversed by default
1752+ when building the initialization system.
1753+ """
1754+ function reverse_transformation_during_initialization (@nospecialize (tf))
1755+ return reverse_transformation_by_default (tf)
1756+ end
1757+
1758+ function __reverse_transformations_helper (fn:: F , sys:: System ) where {F}
1759+ tfs = getmetadata (sys, ReversibleTransformations, []):: Vector{Any}
1760+ new_tfs = []
1761+ for tf in Iterators. reverse (tfs)
1762+ if ! fn (tf):: Bool
1763+ push! (new_tfs, tf)
1764+ continue
1765+ end
1766+ sys = reverse_transformation (sys, tf):: System
1767+ end
1768+ reverse! (new_tfs)
1769+ return setmetadata (sys, ReversibleTransformations, new_tfs):: System
1770+ end
1771+
1772+ """
1773+ $TYPEDSIGNATURES
1774+
1775+ Reverse all reversible transformations ([`with_reversible_transformation`](@ref)) applied
1776+ to `sys` for which [`reverse_transformation_by_default`](@ref) is `true`.
1777+ """
1778+ function reverse_all_default_reversible_transformations (sys:: System )
1779+ return __reverse_transformations_helper (reverse_transformation_by_default, sys)
1780+ end
1781+
1782+ """
1783+ $TYPEDSIGNATURES
1784+
1785+ Reverse all reversible transformations ([`with_reversible_transformation`](@ref)) applied
1786+ to `sys` for which [`reverse_transformation_during_initialization`](@ref) is `true`.
1787+ """
1788+ function reverse_transformations_for_initialization (sys:: System )
1789+ return __reverse_transformations_helper (reverse_transformation_during_initialization, sys)
1790+ end
0 commit comments