Assumptions, Simplification, and Model Design

Last Updated June 11, 2026

Assumptions, simplification, and model design shape every mathematical model before computation begins. A model does not become useful by including everything. It becomes useful by selecting structure, simplifying detail, and making assumptions explicit enough to inspect, test, revise, and communicate.

This is why mathematical modeling is not simply the act of choosing an equation. A model is an organized representation of a question. Its assumptions determine what the model treats as fixed, variable, uncertain, negligible, external, causal, measurable, continuous, discrete, random, linear, homogeneous, bounded, or constrained. Its simplifications determine what is left out. Its design determines what kind of reasoning the model can support.

A well-designed model clarifies the relationship between purpose, structure, evidence, uncertainty, and use. A poorly designed model may still look mathematical, but it can hide weak assumptions, inappropriate simplifications, unsupported parameters, misleading outputs, or conclusions that exceed the model’s domain. Model design is therefore a discipline of judgment, not merely a technical exercise.

Editorial illustration of a scholarly modeling workspace where complex real-world patterns are simplified through assumptions, overlays, boundaries, and formal model diagrams.
Model design depends on assumptions and simplification: deciding what to include, what to ignore, and how complex reality should be represented.

Assumptions and simplifications are not defects by themselves. They are what make modeling possible. The question is whether they are appropriate for the model’s purpose, visible to model users, testable through analysis, and revised when evidence shows they are inadequate.

Why Assumptions Matter

Assumptions matter because they define the world inside the model. They specify what is treated as relevant, constant, measurable, variable, uncertain, external, internal, causal, random, smooth, continuous, linear, independent, homogeneous, or constrained. Before a model produces a number, graph, forecast, simulation, or optimal solution, assumptions have already shaped what the model is capable of saying.

A mathematical model may assume that a population is well mixed, a material is homogeneous, an error term is normally distributed, a system is closed, a parameter is fixed, an objective function represents value, a constraint represents feasibility, or a relationship is linear. Each assumption makes analysis easier. Each also creates a risk if the assumption is false in a way that matters for the model’s purpose.

The purpose of assumption-aware modeling is not to avoid assumptions. A model without assumptions would be as complex as the world itself and therefore unusable. The purpose is to make assumptions explicit, assess their plausibility, test their influence, and communicate their limits.

Assumption role What it enables What it risks
Simplifies the system Makes the model tractable. Removes a feature that drives outcomes.
Defines variables Turns concepts into measurable quantities. Confuses proxies with the underlying phenomenon.
Specifies relationships Allows equations, algorithms, or rules to be written. Uses the wrong functional form or mechanism.
Sets boundaries Clarifies what is inside and outside the model. Excludes externalities, feedbacks, or affected groups.
Supports computation Allows simulation, optimization, or estimation. Hides numerical or algorithmic limitations.
Frames interpretation Explains what outputs mean. Encourages conclusions beyond the model’s domain.

Assumptions are therefore not small notes after the model. They are load-bearing design choices. If they fail, the model’s conclusions may fail with them.

Back to top ↑

Assumptions as Model Architecture

It is useful to think of assumptions as architecture. They hold the model together. They determine which variables can be connected, which parameters can be estimated, which equations are meaningful, which data are relevant, which outputs can be interpreted, and which uses are justified.

For example, a linear regression model assumes a particular relationship between predictors and response. A compartmental epidemic model may assume mixing patterns and transition rates. An optimization model assumes that an objective function and constraints adequately represent the decision. A network model assumes that nodes and edges preserve the relationships that matter. A simulation assumes that its rules and time steps represent the process being modeled.

When assumptions are visible, they can be debated and tested. When they are hidden, the model can appear more objective or general than it really is.

Model element Architectural assumption Review question
Variable The chosen quantity represents the concept of interest. Is this variable a direct measure, proxy, index, or constructed score?
Parameter The parameter is stable enough to use. Is it estimated, calibrated, assumed, or scenario-based?
Function The relationship has the chosen form. Why linear, exponential, logistic, threshold, or nonlinear?
Boundary Excluded elements do not affect the question enough to include. What important effects are outside the model?
Constraint The feasible region represents real limits. Are constraints physical, legal, ethical, financial, or assumed?
Output The output answers the intended question. Does the output support the actual decision or only a convenient metric?

A model’s architecture should be documented. A useful assumption register records the assumption, its role, the evidence supporting it, the risk if it is false, the sensitivity test that should be run, and the status of review. This turns assumptions from invisible background conditions into auditable modeling artifacts.

Back to top ↑

Simplification: Clarifying Without Erasing

Simplification is the act of reducing complexity so that a model can be understood, analyzed, or computed. It is not a failure of modeling. It is one of modeling’s central powers. A map is useful because it leaves out most of the terrain. A free-body diagram is useful because it removes irrelevant visual detail. A stock-flow model is useful because it reduces a complex system to accumulation, inflow, outflow, and constraints.

The danger is not simplification itself. The danger is simplifying away the structure that matters. A model that ignores friction may be useful in one mechanical context and misleading in another. A model that represents a population by averages may be useful for aggregate planning and misleading for equity analysis. A model that treats demand as fixed may be useful for a short calculation and inadequate for long-term policy.

Simplification Clarifies when… Distorts when…
Aggregation Average behavior is the intended object. Variation, inequality, or subgroup behavior matters.
Linearization The system remains near a local operating point. Thresholds, feedback, or saturation dominate.
Fixed parameters Parameters are stable across the use context. Parameters shift across time, location, or regime.
Closed boundary External flows are negligible or controlled. External shocks or interactions drive behavior.
Representative case The representative case captures typical behavior. Edge cases, extremes, or vulnerable groups matter.
Deterministic model Uncertainty is small or not central to the question. Random variation strongly shapes outcomes.

Good simplification should be reversible in thought. A modeler should be able to say what was removed, why it was removed, what risk that creates, and when the removed detail must be restored.

Back to top ↑

Idealization, Approximation, and Distortion

Idealization occurs when a model knowingly uses assumptions that are not literally true. Frictionless planes, perfectly mixed populations, rational agents, continuous media, point masses, representative firms, normal error terms, and fixed carrying capacities are all examples of idealizations. They are not necessarily mistakes. They can isolate mechanisms and make analysis possible.

Approximation is related but distinct. An approximation may represent a complex relationship with a simpler form, such as replacing a nonlinear function with a local linear approximation or using a numerical method to approximate a solution. Approximation is judged by error, stability, and relevance to purpose.

Distortion occurs when idealization or approximation changes the meaning of the model in a way that matters. A useful idealization becomes distortion when users forget that it is an idealization, apply it beyond its domain, or use it to justify decisions that require omitted detail.

Concept Meaning Responsible use
Idealization Knowingly false but useful simplification. State why it helps and when it fails.
Approximation Numerical or formal simplification of a relationship. Estimate error and test sensitivity.
Aggregation Combining many units into a summary variable. Check whether distribution matters.
Parameterization Representing unresolved processes through parameters. Document what the parameter hides.
Distortion Simplification that misleads interpretation. Revise representation or restrict use.

Model design requires knowing which simplifications are harmless, which are useful but fragile, and which are unacceptable for the intended use. This judgment cannot be made from mathematics alone. It depends on purpose, context, evidence, domain knowledge, uncertainty, and consequences.

Back to top ↑

What Model Design Includes

Model design is the organized set of choices that turns a modeling question into a formal and computational object. It includes purpose, boundary, scale, variables, parameters, assumptions, relationships, constraints, outputs, data, computation, validation, and communication.

The design process should begin with the question, not the equation. A model for explanation may be designed differently from a model for prediction. A model for scenario exploration may be designed differently from a model for engineering certification. A model for public deliberation may need interpretability and transparency that a specialized simulation does not provide.

Design choice Question Artifact
Purpose What is the model meant to do? Purpose statement.
Boundary What is inside and outside the model? Boundary note or system diagram.
Scale What spatial, temporal, or organizational scale is represented? Scale definition.
Variables What quantities describe the system? Variable table with units.
Parameters What values shape behavior? Parameter table and source notes.
Assumptions What must be true for the model to be useful? Assumption register.
Relationships How do variables and parameters interact? Equations, rules, algorithms, or diagrams.
Outputs What does the model produce? Output list, diagnostics, plots, intervals.
Validation How will adequacy be assessed? Validation and uncertainty plan.

A strong design links each model component to a reason. A variable should exist because it helps answer the question. A parameter should exist because it shapes relevant behavior. A constraint should exist because it represents a meaningful limit. An output should exist because it supports interpretation, comparison, or decision-making.

Back to top ↑

Major Types of Model Assumptions

Assumptions can be grouped by the role they play. Some assumptions concern the system boundary. Some concern mathematical form. Some concern data, measurement, or parameters. Some concern computation. Some concern how outputs will be interpreted.

Assumption type Example Risk if false
Boundary assumption External shocks are excluded. Important drivers may be ignored.
Scale assumption Monthly time steps are sufficient. Short-term events or delays may disappear.
Homogeneity assumption All units behave similarly. Subgroup variation may be hidden.
Independence assumption Errors or events are independent. Correlation, contagion, or clustering may be missed.
Functional-form assumption The relationship is linear. Nonlinearity, thresholds, or saturation may be missed.
Parameter assumption A rate is constant over time. Regime shifts or context dependence may distort results.
Distributional assumption Error follows a normal distribution. Tail risk or skewness may be understated.
Computational assumption The numerical method is accurate enough. Solver error may be mistaken for model behavior.
Interpretive assumption The output metric represents the decision need. A convenient metric may replace the real question.

Different types of assumptions require different tests. A boundary assumption may require domain review. A functional-form assumption may require residual diagnostics, alternative models, or theoretical justification. A parameter assumption may require sensitivity analysis. A computational assumption may require convergence checks. An interpretive assumption may require stakeholder or decision-context review.

Back to top ↑

Boundary, Scale, and Scope Assumptions

Boundary, scale, and scope assumptions determine where the model begins and ends. They decide what is internal, what is external, what is aggregated, and what is ignored. These assumptions are often more consequential than the equation itself.

A public health model may include biological transmission but exclude trust, compliance, transportation, housing, or institutional capacity. An economic model may include prices and quantities but exclude power, legal constraints, unpaid labor, or ecological damage. An engineering model may include physical loads but exclude maintenance failures or operator behavior. These exclusions may be reasonable for one purpose and unacceptable for another.

Boundary decision Design question Possible consequence
System boundary What processes are inside the model? External effects may be ignored.
Population boundary Who or what is included? Excluded groups may disappear from outputs.
Temporal boundary How far does the model look? Long-term effects may be hidden.
Spatial boundary What location or network is represented? Regional spillovers may be omitted.
Mechanism boundary Which mechanisms are explicit? Important processes may be hidden inside parameters.
Decision boundary Which choices are treated as available? The model may naturalize institutional limits.

Scope should match purpose. A narrow model may be useful for a focused calculation. A broad model may be needed for policy, resilience, or ethical review. A high-resolution model may be needed for engineering detail. A lower-resolution model may be better for conceptual understanding. None is automatically superior.

Back to top ↑

Functional Form and Structural Assumptions

Functional form assumptions specify how variables relate. They are among the most visible mathematical choices in a model. A model may assume a linear, exponential, logistic, threshold, polynomial, power-law, probabilistic, network, or differential relationship. Each form implies a different theory of behavior.

For example, a linear model assumes constant marginal change. An exponential model assumes proportional growth. A logistic model assumes growth slows near a limit. A threshold model assumes qualitative change after a boundary is crossed. A network model assumes that connectivity matters. A stochastic model assumes randomness or uncertainty is structurally important.

Functional form Assumption Useful when Risk
Linear Change is proportional and additive. Local approximation, simple relationships, interpretability. Misses thresholds, saturation, and feedback.
Exponential Growth is proportional to current state. Early growth, compounding, unconstrained expansion. Overstates long-term growth if limits exist.
Logistic Growth slows near capacity. Bounded growth and saturation. Assumes a fixed capacity and simple limiting process.
Threshold Behavior changes after a critical value. Failure, tipping points, regime shifts. Threshold may be uncertain or context-dependent.
Network Connections shape behavior. Contagion, infrastructure, dependency, flow. Edge definitions may dominate conclusions.
Stochastic Random variation matters. Risk, uncertainty, noisy systems, rare events. Distributional assumptions may be weak.

Functional form should not be chosen because it is convenient alone. It should be justified by purpose, theory, evidence, and diagnostics. When functional form is uncertain, model comparison and sensitivity analysis can help reveal whether conclusions depend on the chosen structure.

Back to top ↑

Parameterization and Hidden Complexity

Parameterization is the practice of representing complex or unresolved processes through parameters. It is unavoidable in many models. A transmission rate, friction coefficient, elasticity, decay constant, risk weight, carrying capacity, or loss rate may summarize mechanisms that are not explicitly modeled.

Parameterization is useful because it allows unresolved complexity to enter a model in compact form. It is dangerous when parameters appear more certain, stable, or interpretable than they really are. A single parameter may hide multiple mechanisms, data limitations, context dependence, or structural uncertainty.

Parameter What it may hide Review question
Growth rate Environmental conditions, incentives, adaptation, measurement error. Is the rate stable across time and context?
Transmission rate Behavior, contact patterns, immunity, policy, reporting. Can the rate be estimated independently?
Loss rate Evaporation, leakage, inefficiency, infrastructure condition. Should losses be process-based rather than proportional?
Risk weight Value judgment, empirical association, policy preference. Who chose the weight and why?
Elasticity Behavioral response, market structure, income effects. Does it apply outside the estimation context?
Capacity Physical limit, operating rule, political constraint, safety margin. Is capacity fixed, usable, or scenario-dependent?

A strong model design distinguishes estimated parameters, calibrated parameters, assumed parameters, scenario parameters, and uncertain parameters. Treating all numbers as equally known is a common source of false confidence.

Back to top ↑

Uncertainty and Sensitivity

Uncertainty analysis asks how uncertain the model output is. Sensitivity analysis asks which inputs, assumptions, or parameters most influence the output. These are not the same question, but they belong together in assumption-aware design.

If a conclusion depends strongly on an assumption that is poorly justified, the conclusion should be reported cautiously. If a parameter has little influence over the output, it may not deserve extensive estimation effort. If a boundary assumption changes the model’s conclusion, the boundary must be reconsidered. Sensitivity analysis helps reveal which simplifications are harmless, which are fragile, and which are unacceptable.

\[
S_i=\frac{\partial y}{\partial p_i}
\]

Interpretation: A local sensitivity measure \(S_i\) describes how model output \(y\) changes in response to a small change in parameter \(p_i\).

Analysis Question Use
One-at-a-time sensitivity What happens when one parameter changes? Simple first-pass assumption review.
Scenario analysis What happens under alternative plausible worlds? Boundary, policy, and future-condition exploration.
Monte Carlo uncertainty What range of outputs follows from uncertain inputs? Output intervals and risk summaries.
Global sensitivity Which inputs drive output variation across ranges? Prioritizing data collection and robust design.
Structural sensitivity What happens under alternative model forms? Testing dependence on functional form.
Stress testing What happens under extreme but plausible conditions? Robustness and failure-mode analysis.

Sensitivity analysis is not a decorative add-on. It is one of the main ways modelers learn whether assumptions matter. A model design that cannot be tested against assumption changes is difficult to trust.

Back to top ↑

Validation and Assumption Testing

Validation asks whether the model is adequate for its intended purpose. It is not a generic stamp of truth. A model may be valid for classroom demonstration, exploratory scenario comparison, or conceptual explanation while being invalid for operational forecasting, safety certification, or policy deployment.

Assumptions are central to validation. A model’s assumptions should be compared with evidence, domain knowledge, diagnostics, and intended use. Some assumptions can be tested directly. Others can be examined through sensitivity analysis, model comparison, expert review, or stress testing.

Assumption Possible test Possible revision
Linearity Residual patterns, nonlinear alternatives, theory review. Add nonlinear or threshold term.
Constant parameter Time-varying estimates, subgroup comparison. Use time-varying or context-specific parameter.
Homogeneity Subgroup diagnostics, spatial analysis. Disaggregate by group or location.
Independence Autocorrelation, clustering, network structure. Add correlation, dependence, or network layer.
Closed boundary External shock review, domain mapping. Add external drivers or boundary expansion.
Distributional form Diagnostic plots, tail analysis, alternative distributions. Use robust or nonparametric model.
Numerical adequacy Solver comparison, convergence checks. Refine method, step size, grid, or tolerance.

Validation should include an adequacy statement that says what the model is adequate for, under what assumptions, with what evidence, and with what limitations. This is more honest than simply calling a model valid.

Back to top ↑

Mathematical Lens: Assumptions as Constraints on Model Worlds

One way to understand assumptions mathematically is to treat them as constraints on the space of possible model worlds. Let \(W\) represent the real-world target system and \(M\) represent the model. The abstraction map selects some features of \(W\) and turns them into a formal structure:

\[
\alpha: W \rightarrow M
\]

Interpretation: The abstraction map \(\alpha\) translates selected features of the world into a model structure.

A model can be represented as:

\[
M=(V,P,A,R,C,O)
\]

Interpretation: A model contains variables \(V\), parameters \(P\), assumptions \(A\), relationships \(R\), constraints \(C\), and outputs \(O\).

Assumptions restrict the model’s admissible worlds. If \(A\) is the set of assumptions, then the model reasons only inside the subset of possibilities consistent with those assumptions:

\[
\Omega_A=\{\omega\in\Omega:\omega \text{ satisfies } A\}
\]

Interpretation: The assumption set \(A\) restricts the possible model worlds from \(\Omega\) to \(\Omega_A\).

Model design can then be understood as choosing the formal structure that preserves what matters for a purpose \(U\):

\[
M^\ast=\arg\min_{M\in\mathcal{M}} L(M;U,E,A)
\]

Interpretation: A model design \(M^\ast\) is chosen from possible models \(\mathcal{M}\) by considering purpose \(U\), evidence \(E\), and assumptions \(A\).

This expression is not meant to reduce model design to a mechanical optimization problem. It is a reminder that design is comparative. Modelers choose among possible representations, and those choices should be judged by purpose, evidence, assumptions, uncertainty, and consequences.

Back to top ↑

Example: Designing a Simplified Resource Model

Consider a resource system such as a reservoir, inventory, or stored energy supply. The real-world system may include inflows, outflows, storage, capacity, losses, quality, users, infrastructure, policy, uncertainty, seasonal variation, and distributional consequences. A first model cannot include everything.

A simplified stock-flow model might define:

\[
S_t=\text{stored resource at time }t
\]

Interpretation: \(S_t\) abstracts a complex resource system into one aggregate state variable.

The update rule may be:

\[
S_{t+1}=S_t+I_t-D_t-L_t
\]

Interpretation: Storage changes through inflow \(I_t\), demand \(D_t\), and losses \(L_t\).

A bounded version adds nonnegativity and capacity:

\[
S_{t+1}=\min\left(K,\max\left(0,S_t+I_t-D_t-L_t\right)\right)
\]

Interpretation: Storage cannot fall below zero or exceed capacity \(K\).

This simple model is useful because it preserves accumulation, depletion, and capacity. It is limited because it omits spatial variation, legal allocation, ecological flows, user heterogeneity, stochastic inflow, quality constraints, and institutional response. The model’s design is appropriate only for purposes that do not require those omitted details.

Design choice Simplification Risk Extension
One state variable Aggregate storage. Hides spatial distribution and access. Disaggregated or spatial model.
Fixed capacity Constant upper bound. Ignores operating rules and infrastructure change. Time-varying capacity or rule curve.
Deterministic inflow Known or scenario-based input. Understates drought uncertainty. Stochastic inflow ensemble.
Simple loss term Loss proportional to storage. Misses temperature, leakage, and surface-area effects. Process-based loss model.
Aggregate demand Single demand term. Hides user groups and distributional effects. Demand segments or allocation model.
Shortage output Counts shortage periods. Misses severity and affected users. Severity, duration, and equity metrics.

The model is not wrong because it is simple. It becomes wrong if it is used for questions that require the details it omits.

Back to top ↑

Python Workflow: Assumption Register, Scenario Model, and Sensitivity Audit

The Python workflow below treats assumptions as first-class modeling artifacts. It defines assumptions, simulates a simplified stock-flow model, runs scenario comparisons, calculates sensitivity indicators, and exports a model design card.

# assumptions_model_design_workflow.py
# Dependency-light workflow for assumption-aware model design.

from __future__ import annotations

from dataclasses import asdict, dataclass
from pathlib import Path
import csv
import json
from statistics import mean


ARTICLE_ROOT = Path(__file__).resolve().parents[1]
OUTPUTS = ARTICLE_ROOT / "outputs"
TABLES = OUTPUTS / "tables"
JSON_DIR = OUTPUTS / "json"


@dataclass(frozen=True)
class ModelAssumption:
    key: str
    statement: str
    assumption_type: str
    role: str
    risk_if_false: str
    sensitivity_test: str
    review_status: str


@dataclass(frozen=True)
class ResourceScenario:
    name: str
    initial_stock: float
    capacity: float
    inflow: float
    demand: float
    loss_rate: float
    periods: int


def bounded_update(stock: float, inflow: float, demand: float, losses: float, capacity: float) -> float:
    return min(capacity, max(0.0, stock + inflow - demand - losses))


def simulate_resource(scenario: ResourceScenario) -> list[dict[str, float | str | int]]:
    if scenario.initial_stock < 0:
        raise ValueError("initial_stock must be nonnegative.")
    if scenario.capacity <= 0: raise ValueError("capacity must be positive.") if scenario.initial_stock > scenario.capacity:
        raise ValueError("initial_stock cannot exceed capacity.")

    stock = scenario.initial_stock
    rows: list[dict[str, float | str | int]] = []

    for period in range(scenario.periods + 1):
        losses = scenario.loss_rate * stock
        shortage = max(0.0, scenario.demand + losses - (stock + scenario.inflow))

        rows.append({
            "scenario": scenario.name,
            "period": period,
            "stock": round(stock, 6),
            "inflow": round(scenario.inflow, 6),
            "demand": round(scenario.demand, 6),
            "losses": round(losses, 6),
            "shortage": round(shortage, 6),
            "capacity": round(scenario.capacity, 6),
        })

        stock = bounded_update(stock, scenario.inflow, scenario.demand, losses, scenario.capacity)

    return rows


def summarize(rows: list[dict[str, float | str | int]]) -> dict[str, float | str | int]:
    stocks = [float(row["stock"]) for row in rows]
    shortages = [float(row["shortage"]) for row in rows]

    return {
        "scenario": str(rows[0]["scenario"]),
        "final_stock": round(stocks[-1], 6),
        "mean_stock": round(mean(stocks), 6),
        "min_stock": round(min(stocks), 6),
        "shortage_periods": sum(1 for value in shortages if value > 0),
        "total_shortage": round(sum(shortages), 6),
        "shortage_risk": round(sum(1 for value in shortages if value > 0) / len(rows), 6),
    }


def assumption_register() -> list[ModelAssumption]:
    return [
        ModelAssumption(
            key="aggregate_stock",
            statement="The resource system is represented by one aggregate stock variable.",
            assumption_type="abstraction",
            role="Keeps the first model interpretable.",
            risk_if_false="Spatial, subgroup, or access differences may be hidden.",
            sensitivity_test="Compare aggregate and disaggregated versions.",
            review_status="review",
        ),
        ModelAssumption(
            key="fixed_capacity",
            statement="Capacity is fixed within each scenario.",
            assumption_type="boundary",
            role="Defines the upper stock constraint.",
            risk_if_false="Operating rules or infrastructure changes may alter usable capacity.",
            sensitivity_test="Compare lower and higher capacity scenarios.",
            review_status="active",
        ),
        ModelAssumption(
            key="deterministic_inflow",
            statement="Inflow is represented as a scenario value rather than a random process.",
            assumption_type="uncertainty",
            role="Keeps the demonstration deterministic.",
            risk_if_false="Shortage risk may be understated.",
            sensitivity_test="Add low, baseline, and high inflow scenarios.",
            review_status="review",
        ),
        ModelAssumption(
            key="proportional_losses",
            statement="Losses are proportional to current stock.",
            assumption_type="functional_form",
            role="Provides a simple loss mechanism.",
            risk_if_false="Losses may depend on temperature, leakage, or season.",
            sensitivity_test="Compare loss-rate scenarios.",
            review_status="review",
        ),
    ]


def assumption_risk_score(assumption: ModelAssumption) -> float:
    base = {"active": 1.0, "review": 5.0, "revise": 8.0, "archive": 2.0}.get(
        assumption.review_status.lower(),
        4.0,
    )
    if assumption.assumption_type in {"uncertainty", "functional_form"}:
        base += 2.0
    if "hidden" in assumption.risk_if_false.lower() or "understated" in assumption.risk_if_false.lower():
        base += 1.5
    return round(base, 3)


def write_csv(path: Path, rows: list[dict[str, object]]) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    if not rows:
        raise ValueError(f"No rows supplied for {path}")
    with path.open("w", newline="", encoding="utf-8") as handle:
        writer = csv.DictWriter(handle, fieldnames=list(rows[0].keys()))
        writer.writeheader()
        writer.writerows(rows)


def write_json(path: Path, payload: object) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("w", encoding="utf-8") as handle:
        json.dump(payload, handle, indent=2, sort_keys=True)


def main() -> None:
    scenarios = [
        ResourceScenario("baseline", 80.0, 100.0, 8.0, 6.0, 0.015, 60),
        ResourceScenario("low_inflow", 80.0, 100.0, 5.0, 6.0, 0.015, 60),
        ResourceScenario("higher_losses", 80.0, 100.0, 8.0, 6.0, 0.035, 60),
        ResourceScenario("lower_capacity", 70.0, 75.0, 8.0, 6.0, 0.015, 60),
        ResourceScenario("compound_stress", 70.0, 80.0, 5.0, 7.0, 0.030, 60),
    ]

    all_rows: list[dict[str, object]] = []
    summary_rows: list[dict[str, object]] = []

    for scenario in scenarios:
        rows = simulate_resource(scenario)
        all_rows.extend(rows)
        summary_rows.append(summarize(rows))

    assumptions = assumption_register()
    assumption_rows = [
        {**asdict(item), "assumption_risk_score": assumption_risk_score(item)}
        for item in assumptions
    ]

    write_csv(TABLES / "resource_scenario_timeseries.csv", all_rows)
    write_csv(TABLES / "resource_scenario_summary.csv", summary_rows)
    write_csv(TABLES / "assumption_register.csv", assumption_rows)

    write_json(JSON_DIR / "model_design_card.json", {
        "article": "Assumptions, Simplification, and Model Design",
        "formal_model": "S[t+1] = min(K, max(0, S[t] + I[t] - D[t] - L[t]))",
        "model_design_purpose": "Demonstrate assumption-aware simplification and scenario review.",
        "assumptions": assumption_rows,
        "scenario_summaries": summary_rows,
        "revision_triggers": [
            "high assumption risk score",
            "shortage periods in stress scenarios",
            "conclusion sensitive to low inflow",
            "omitted heterogeneity affects intended use",
            "validation evidence does not support design assumptions",
        ],
    })

    print("Assumption-aware model design workflow complete.")
    print(f"Wrote outputs to {OUTPUTS}")


if __name__ == "__main__":
    main()

This workflow makes assumptions visible as model artifacts. It also connects assumptions to risk scores, sensitivity tests, scenario results, and revision triggers.

Back to top ↑

R Workflow: Assumption Review and Scenario Diagnostics

The R workflow below reviews generated outputs and produces a table of assumption and scenario status. It is designed for model review, communication, and early diagnostic reporting.

# assumptions_model_design_review.R
# Base R workflow for assumption and scenario diagnostics.

args <- commandArgs(trailingOnly = FALSE)
file_arg <- grep("^--file=", args, value = TRUE) if (length(file_arg) > 0) {
  script_path <- normalizePath(sub("^--file=", "", file_arg[1]), mustWork = TRUE)
  article_root <- normalizePath(file.path(dirname(script_path), ".."), mustWork = TRUE)
} else {
  article_root <- getwd()
}

tables_dir <- file.path(article_root, "outputs", "tables")
figures_dir <- file.path(article_root, "outputs", "figures")
dir.create(tables_dir, recursive = TRUE, showWarnings = FALSE)
dir.create(figures_dir, recursive = TRUE, showWarnings = FALSE)

summary_path <- file.path(tables_dir, "resource_scenario_summary.csv")
assumption_path <- file.path(tables_dir, "assumption_register.csv")

if (!file.exists(summary_path)) {
  stop("Missing resource_scenario_summary.csv. Run the Python workflow first.")
}

summary_data <- read.csv(summary_path, stringsAsFactors = FALSE)

summary_data$scenario_review <- ifelse( summary_data$shortage_periods > 0,
  "requires review",
  "acceptable under stated assumptions"
)

write.csv(
  summary_data,
  file.path(tables_dir, "r_scenario_design_review.csv"),
  row.names = FALSE
)

if (file.exists(assumption_path)) {
  assumptions <- read.csv(assumption_path, stringsAsFactors = FALSE)

  assumptions$priority <- ifelse( assumptions$assumption_risk_score >= 7,
    "high",
    ifelse(assumptions$assumption_risk_score >= 5, "medium", "low")
  )

  write.csv(
    assumptions,
    file.path(tables_dir, "r_assumption_review_queue.csv"),
    row.names = FALSE
  )
}

png(file.path(figures_dir, "r_shortage_risk_by_scenario.png"), width = 1100, height = 720)

barplot(
  height = summary_data$shortage_risk,
  names.arg = summary_data$scenario,
  las = 2,
  ylab = "Shortage risk",
  main = "Shortage Risk Under Simplified Model Assumptions"
)

grid()
dev.off()

print(summary_data)

The R layer shows which scenarios require review and which assumptions deserve priority. It can be extended with uncertainty intervals, residual diagnostics, parameter sweeps, and more formal sensitivity analysis.

Back to top ↑

Haskell Workflow: Typed Assumption and Design Records

Haskell strengthens this article because assumptions and design choices are not all the same kind of object. A boundary assumption differs from a functional-form assumption. A simplification differs from a validation claim. A parameter differs from an output metric. Types make those distinctions harder to blur.

{-# OPTIONS_GHC -Wall #-}

module Main where

data AssumptionType
  = BoundaryAssumption
  | ScaleAssumption
  | FunctionalFormAssumption
  | ParameterAssumption
  | UncertaintyAssumption
  | ComputationalAssumption
  | InterpretiveAssumption
  deriving (Eq, Show)

data ReviewStatus
  = Active
  | RequiresReview
  | RequiresSensitivityTest
  | RequiresValidation
  | Revise
  deriving (Eq, Show)

data ModelDesignObject
  = StateVariable String
  | Parameter String
  | Constraint String
  | Assumption String
  | OutputMetric String
  | Simplification String
  deriving (Eq, Show)

data DesignRecord = DesignRecord
  { designObject :: ModelDesignObject
  , assumptionType :: AssumptionType
  , statement :: String
  , riskIfFalse :: String
  , status :: ReviewStatus
  , reviewQuestion :: String
  } deriving (Eq, Show)

records :: [DesignRecord]
records =
  [ DesignRecord
      (Simplification "aggregate stock")
      BoundaryAssumption
      "The resource system is represented by one aggregate stock."
      "Spatial variation, subgroup access, or local shortage may be hidden."
      RequiresReview
      "Does aggregate storage preserve the structure needed for the intended use?"
  , DesignRecord
      (Parameter "K")
      ParameterAssumption
      "Capacity is treated as fixed within each scenario."
      "Usable capacity may depend on operating rules or infrastructure condition."
      RequiresSensitivityTest
      "How do conclusions change under lower and higher capacity?"
  , DesignRecord
      (Assumption "proportional losses")
      FunctionalFormAssumption
      "Losses are proportional to current stock."
      "Losses may depend on season, temperature, leakage, or surface area."
      RequiresSensitivityTest
      "Should losses be process-based rather than proportional?"
  , DesignRecord
      (OutputMetric "shortage risk")
      InterpretiveAssumption
      "Shortage periods are treated as a useful summary of model risk."
      "Severity, duration, and affected users may be hidden."
      RequiresValidation
      "Does this output metric represent the decision need?"
  ]

needsReview :: DesignRecord -> Bool
needsReview record =
  case status record of
    Active -> False
    _ -> True

main :: IO ()
main = do
  putStrLn "Typed assumption and model design records:"
  mapM_ print records

  putStrLn "\nRecords requiring review:"
  mapM_ print (filter needsReview records)

This typed layer supports model governance. It prevents assumptions, parameters, constraints, simplifications, and outputs from being treated as interchangeable pieces of text. That distinction matters in professional model review.

Back to top ↑

GitHub Repository

The companion repository for this article is designed as a reproducible mathematical-modeling workspace. It contains article-specific code, data, documentation, notebooks, schemas, and generated outputs for assumption registers, simplification audits, resource stock-flow modeling, scenario comparison, sensitivity review, typed Haskell design records, validation planning, and reproducible engineering/statistical workflows.

Back to top ↑

A Practical Method for Assumption-Aware Model Design

A practical method for assumption-aware model design begins by treating assumptions as design objects. The method below can be used before model implementation, during review, or after diagnostics reveal problems.

Step Task Question Artifact
1 State purpose What is the model meant to explain, predict, simulate, optimize, or support? Purpose statement.
2 List assumptions What must be assumed for the model to work? Assumption register.
3 Classify assumptions Are they boundary, scale, functional, parameter, uncertainty, computational, or interpretive assumptions? Assumption type table.
4 Record simplifications What has been omitted, aggregated, idealized, or parameterized? Simplification log.
5 Assess risk What happens if each assumption is false? Risk-if-false column.
6 Define sensitivity tests Which assumptions should be varied? Sensitivity test plan.
7 Run scenarios How do outputs change under plausible alternatives? Scenario outputs.
8 Validate where possible What evidence supports or challenges the assumptions? Validation note.
9 Revise Which assumptions should be changed, qualified, or removed? Revision log.

This method makes model design inspectable. It does not eliminate judgment. It makes judgment visible enough to be improved.

Back to top ↑

Common Pitfalls

Assumption and simplification failures often appear technical, but many begin as design failures. The following pitfalls are especially common.

  • Hidden assumptions: relying on assumptions that are never stated or reviewed.
  • Equation-first design: choosing a familiar equation before defining purpose, boundary, and scale.
  • Over-aggregation: hiding subgroup variation, spatial differences, or distributional effects.
  • Linearization without review: using a linear approximation where thresholds, saturation, or feedback matter.
  • Parameter overconfidence: treating calibrated, assumed, or scenario-based values as known constants.
  • Calibration confusion: assuming good fit validates the model’s structure.
  • Simplification drift: using a simplified model for more demanding purposes than it was designed for.
  • Boundary blindness: ignoring excluded processes that drive outcomes.
  • False precision: reporting outputs without uncertainty or sensitivity context.
  • Model authority error: treating model output as a decision rather than as evidence for judgment.

These pitfalls do not mean models should become more complicated by default. They mean models should be designed with explicit assumptions, visible simplifications, and reviewable limits.

Back to top ↑

Conclusion: Model Design Is Disciplined Judgment

Assumptions, simplification, and model design are not preliminary details. They are the foundation of mathematical modeling. Before a model computes, predicts, simulates, or optimizes, it has already selected a world of possible reasoning through its assumptions.

A useful model simplifies. It must. But useful simplification preserves the structure needed for the question and makes omitted detail visible. Responsible model design states assumptions, tests sensitivity, compares alternatives, validates where possible, and communicates uncertainty. It also recognizes that the right model depends on purpose. A model adequate for explanation may be inadequate for prediction. A model useful for scenario exploration may be inadequate for operational decisions.

The discipline of modeling is therefore not the search for the most complex representation. It is the search for a representation whose assumptions, simplifications, and design choices are appropriate for the question, supported by evidence, transparent about uncertainty, and honest about limits.

Mathematical models clarify the world by simplifying it. Model design is the practice that determines whether that simplification becomes insight or distortion.

Back to top ↑

Back to top ↑

Further Reading

Back to top ↑

References

Back to top ↑

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top