From 7c575df36fdeea58b95eccbb5323b37cd64bcfbd Mon Sep 17 00:00:00 2001 From: Mirek Kratochvil Date: Thu, 16 Jan 2025 21:19:37 +0100 Subject: [PATCH] finalize the algebra (add `inject_interface` to extend stoichiometries "to the right") --- src/builders/interface.jl | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/builders/interface.jl b/src/builders/interface.jl index 3d0fed2b..55cba4b4 100644 --- a/src/builders/interface.jl +++ b/src/builders/interface.jl @@ -100,3 +100,35 @@ Overload of [`interface_constraints`](@ref) for general key-value containers. interface_constraints(kv; kwargs...) = interface_constraints(kv...; kwargs...) export interface_constraints + +""" +$(TYPEDSIGNATURES) + +Glue an interface made of additional variables into a constraint system that +lacks one. Returns a tuple of a "module" and its "interface", usable in +[`interface_constraint`](@ref). + +The values in `interface` are injected into `constraints` that have the same +"path" in the constraint tree. Attempts to inject into missing `constraints` +and mismatches between leaf constraints and subtrees are ignored. The output +consists of the extended `constraints` and `interface` with renumbered +variables (in particular, numbering of original variables in `constraints` is +retained). Constraints in both trees retain their bounds. + +In metabolic modeling terms, this adds interfaces that contribute to any +constrained quantity in a model. For example, one may conveniently create new +exchange reactions to contribute to an existing metabolite balance, which can +in turn be used as an interface in a more complex model. +""" +function inject_interface(constraints::C.ConstraintTree, interface::C.ConstraintTree) + go(cs::C.ConstraintTree, iface::C.ConstraintTree) = + C.ConstraintTree(k => haskey(iface, k) ? go(v, iface[k]) : v for (k, v) in cs) + go(cs::C.Constraint, iface::C.Constraint) = + C.Constraint(value = cs.value + iface.value, bound = cs.bound) + go(_, _) = cs # any non-matching interface is simply ignored + + interface_ = C.incr_var_idxs(interface, C.var_count(constraints)) + return (go(constraints, interface_), interface_) +end + +export inject_interface