#lang racket ;;; dds/rs ;;; Definitions for working with reaction systems. (require "utils.rkt") (provide ;; Structures (struct-out reaction) ;; Functions (contract-out [enabled? (-> reaction? (set/c symbol?) boolean?)] [list-enabled (-> reaction-system/c (set/c species?) (listof symbol?))] [union-products (-> reaction-system/c (listof symbol?) (set/c species?))] [apply-rs (-> reaction-system/c (set/c species?) (set/c species?))] [ht-str-triples->rs (-> (hash/c symbol? (list/c string? string? string?)) reaction-system/c)]) ;; Predicates (contract-out [species? (-> any/c boolean?)]) ;; Contracts (contract-out [reaction-system/c contract?]) ;; Syntax unorg-rs) ;;; ================= ;;; Basic definitions ;;; ================= ;;; A species is a symbol. (define species? symbol?) ;;; A reaction is a triple of sets, giving the reactants, the ;;; inhibitors, and the products, respectively. (struct reaction (reactants inhibitors products) #:transparent) ;;; A reaction is enabled on a set if all of its reactants are in the ;;; set and none of its inhibitors are. (define/match (enabled? r s) [((reaction r i p) s) (and (subset? r s) (set-empty? (set-intersect i s)))]) ;;; A reaction system is a dictionary mapping reaction names to ;;; reactions. (define reaction-system/c (hash/c symbol? reaction?)) ;;; Returns the list of reaction names enabled on a given set. (define (list-enabled rs s) (for/list ([(name reaction) (in-hash rs)] #:when (enabled? reaction s)) name)) ;;; Returns the union of the product sets of the given reactions in a ;;; reaction system. ;;; ;;; This function can be seen as producing the result of the ;;; application of the given reactions to a set. Clearly, it does not ;;; check whether the reactions are actually enabled. (define (union-products rs as) (apply set-union (for/list ([a as]) (reaction-products (hash-ref rs a))))) ;;; Applies a reaction system to a set. (define (apply-rs rs s) (let ([as (list-enabled rs s)]) (union-products rs as))) ;;; ==================== ;;; Org-mode interaction ;;; ==================== ;;; This section contains some useful primitives for Org-mode ;;; interoperability. ;;; Reads a list of species from a string. (define (read-symbol-list str) (string->any (string-append "(" str ")"))) ;;; Converts a triple of strings to a reaction. (define/match (str-triple->reaction lst) [((list str-reactants str-inhibitors str-products)) (reaction (list->set (read-symbol-list str-reactants)) (list->set (read-symbol-list str-inhibitors)) (list->set (read-symbol-list str-products)))]) ;;; Converts a hash table mapping reaction names to triples of strings ;;; to a reaction system. (define (ht-str-triples->rs ht) (for/hash ([(a triple) (in-hash ht)]) (values a (str-triple->reaction triple)))) ;;; Chains ht-str-triples->rs with unorg. (define-syntax-rule (unorg-rs str) (ht-str-triples->rs (unorg str)))