Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Executable cadCAD Specification

cadCAD (Complex Adaptive Dynamics Computer-Aided Design) is a language for encoding Generalised Dynamical Systems (GDS) as computer programs.

This is an (informal) executable specification for the structure of a cadCAD model, based on https://github.com/cadCAD-org/spec. The README itself is the spec: a Haskell literate program (.lhs) that is testable and executable.

make run
make test

See Generalised Dynamical Systems and Semantic Disambiguation and Term Standardisation for Generalised Dynamical Systems (GDS) for background.

The goals of this codebase are to:

  • develop a foundation for building cadCAD reference implementations
  • standardise the terminology used to refer to the structure of a cadCAD model

Imports

module Main where

import qualified Data.Map.Strict as Map
import Data.Map (Map(), toList, fromListWith)
import Data.List (groupBy)
import Data.Sort (sortOn)
import Data.Tuple (fst)
import Data.Maybe (fromMaybe)

Types

Model State

type StateVariableKey = String
type StateVariableValue = Float
type StateVariable = (StateVariableKey, StateVariableValue)
type State = Map StateVariableKey StateVariableValue
type StateHistory = [State]

Model Policies

type PolicySignalKey = String
type PolicySignalValue = Float
type PolicySignal = (PolicySignalKey, PolicySignalValue)

Model Functions

type PolicyFunction = State -> [PolicySignal]
type StateUpdateFunction = State -> [PolicySignal] -> StateVariable

Model Structure

data PartialStateUpdateBlock = PartialStateUpdateBlock { policies :: [PolicyFunction], variables :: [StateUpdateFunction] }
type Model = [PartialStateUpdateBlock]

Simulation Logic

partialStateUpdate :: State -> PartialStateUpdateBlock -> State
partialStateUpdate s psub = updateState s $ applyPartialStateUpdate s
    where
        applyPartialStateUpdate :: State -> StateVariable
        applyPartialStateUpdate s = stateUpdateFunction s $ policyFunction s
            where
                policyFunction = head $ policies psub
                stateUpdateFunction = head $ variables psub
        updateState :: State -> StateVariable -> State
        updateState s v = Map.insert (fst v) (snd v) s

policySignalAggregation :: Num b => [(PolicySignalKey, b)] -> [(PolicySignalKey, b)]
policySignalAggregation = map sumGroup . groupBy fstEq . sortOn fst
  where
    sumGroup (x:xs) = (fst x, sum $ map snd (x:xs))
    sumGroup _ = error "This can never happen - groupBy cannot return empty groups"
    fstEq (a, _) (b, _) = a == b

simulation :: Model -> State -> StateHistory
simulation m initialState = take 10 (iterate (\s -> partialStateUpdate s (head m)) initialState)

Model Configuration

stateUpdateFunction :: StateUpdateFunction
stateUpdateFunction s _ = (\v -> ("a", v)) $ (+) 1 $ fromMaybe 0 (Map.lookup "a" s)

policyFunction :: PolicyFunction
policyFunction _ = [("signal", 1)]

partialStateUpdateBlock :: PartialStateUpdateBlock
partialStateUpdateBlock = PartialStateUpdateBlock [policyFunction] [stateUpdateFunction]

model = [partialStateUpdateBlock, partialStateUpdateBlock]

initialState :: State
initialState = Map.fromList [("a", 0), ("b", 0)]

Simulation Execution

results = simulation model initialState

main :: IO ()
main = print $ results

Simulation Results

[fromList [("a",0.0),("b",0.0)],fromList [("a",1.0),("b",0.0)],fromList [("a",2.0),("b",0.0)],fromList [("a",3.0),("b",0.0)],fromList [("a",4.0),("b",0.0)],fromList [("a",5.0),("b",0.0)],fromList [("a",6.0),("b",0.0)],fromList [("a",7.0),("b",0.0)],fromList [("a",8.0),("b",0.0)],fromList [("a",9.0),("b",0.0)]]

About

An executable cadCAD specification

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages