Skip to content

Commit cf96c18

Browse files
tim-at-toposepatters
authored andcommitted
split out signed stock-flow into new theory
1 parent 64e9edf commit cf96c18

File tree

7 files changed

+106
-26
lines changed

7 files changed

+106
-26
lines changed

packages/backend/pkg/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import type { NewPermissions } from "./NewPermissions.ts";
2121
import type { UserSummary } from "./UserSummary.ts";
2222
import type { UsernameStatus } from "./UsernameStatus.ts";
2323
import type { UserProfile } from "./UserProfile.ts";
24-
import type { RefStub } from "./RefStub.ts";
2524
import type { Paginated } from "./Paginated.ts";
25+
import type { RefStub } from "./RefStub.ts";
2626
import type { RefQueryParams } from "./RefQueryParams.ts";
2727

2828
export type { RpcResult } from "./RpcResult.ts";
@@ -36,8 +36,8 @@ export type { NewPermissions } from "./NewPermissions.ts";
3636
export type { UserSummary } from "./UserSummary.ts";
3737
export type { UsernameStatus } from "./UsernameStatus.ts";
3838
export type { UserProfile } from "./UserProfile.ts";
39-
export type { RefStub } from "./RefStub.ts";
4039
export type { Paginated } from "./Paginated.ts";
40+
export type { RefStub } from "./RefStub.ts";
4141
export type { RefQueryParams } from "./RefQueryParams.ts";
4242

4343
export type QubitServer = { new_ref: Mutation<[content: JsonValue, ], RpcResult<string>>, get_doc: Query<[ref_id: string, ], RpcResult<RefDoc>>, head_snapshot: Query<[ref_id: string, ], RpcResult<JsonValue>>, create_snapshot: Mutation<[ref_id: string, ], RpcResult<null>>, delete_ref: Mutation<[ref_id: string, ], RpcResult<null>>, restore_ref: Mutation<[ref_id: string, ], RpcResult<null>>, get_permissions: Query<[ref_id: string, ], RpcResult<Permissions>>, set_permissions: Mutation<[ref_id: string, new: NewPermissions, ], RpcResult<null>>, validate_session: Query<[], RpcResult<null>>, sign_up_or_sign_in: Mutation<[], RpcResult<null>>, user_by_username: Query<[username: string, ], RpcResult<UserSummary | null>>, username_status: Query<[username: string, ], RpcResult<UsernameStatus>>, get_active_user_profile: Query<[], RpcResult<UserProfile>>, set_active_user_profile: Mutation<[user: UserProfile, ], RpcResult<null>>, search_ref_stubs: Query<[query_params: RefQueryParams, ], RpcResult<Paginated<RefStub>>>, get_ref_children_stubs: Query<[ref_id: string, ], RpcResult<Array<RefStub>>> };

packages/catlog/src/stdlib/analyses/ode/mass_action.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ impl Default for StockFlowMassActionAnalysis {
230230
Self {
231231
stock_ob_type,
232232
flow_mor_type,
233-
pos_link_mor_type: TabMorType::Basic(name("PositiveLink")),
233+
pos_link_mor_type: TabMorType::Basic(name("Link")),
234234
neg_link_mor_type: TabMorType::Basic(name("NegativeLink")),
235235
}
236236
}
@@ -342,8 +342,20 @@ mod tests {
342342
use crate::stdlib::{models::*, theories::*};
343343

344344
#[test]
345-
fn positive_backward_link_dynamics() {
345+
fn backward_link_dynamics() {
346346
let th = Rc::new(th_category_links());
347+
let model = backward_link(th);
348+
let sys = StockFlowMassActionAnalysis::default().build_system(&model);
349+
let expected = expect!([r#"
350+
dx = ((-1) f) x y
351+
dy = f x y
352+
"#]);
353+
expected.assert_eq(&sys.to_string());
354+
}
355+
356+
#[test]
357+
fn positive_backward_link_dynamics() {
358+
let th = Rc::new(th_category_signed_links());
347359
let model = positive_backward_link(th);
348360
let sys = StockFlowMassActionAnalysis::default().build_system(&model);
349361
let expected = expect!([r#"
@@ -355,7 +367,7 @@ mod tests {
355367

356368
#[test]
357369
fn negative_backward_link_dynamics() {
358-
let th = Rc::new(th_category_links());
370+
let th = Rc::new(th_category_signed_links());
359371
let model = negative_backward_link(th);
360372
let sys = StockFlowMassActionAnalysis::default().build_system(&model);
361373
let expected = expect!([r#"

packages/catlog/src/stdlib/models.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub fn positive_backward_link(th: Rc<DiscreteTabTheory>) -> DiscreteTabModel {
122122
name("link"),
123123
name("y").into(),
124124
model.tabulated_gen(name("f")),
125-
TabMorType::Basic(name("PositiveLink")),
125+
TabMorType::Basic(name("Link")),
126126
);
127127
model
128128
}

packages/catlog/src/stdlib/theories.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,7 @@ pub fn th_category_signed_links() -> DiscreteTabTheory {
127127
let mut th = DiscreteTabTheory::new();
128128
th.add_ob_type(name("Object"));
129129
let ob_type = TabObType::Basic(name("Object"));
130-
th.add_mor_type(
131-
name("PositiveLink"),
132-
ob_type.clone(),
133-
th.tabulator(th.hom_type(ob_type.clone())),
134-
);
130+
th.add_mor_type(name("Link"), ob_type.clone(), th.tabulator(th.hom_type(ob_type.clone())));
135131
th.add_mor_type(
136132
name("NegativeLink"),
137133
ob_type.clone(),

packages/frontend/src/stdlib/theories.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ stdTheories.add(
9292
async () => (await import("./theories/primitive-stock-flow")).default,
9393
);
9494

95+
stdTheories.add(
96+
{
97+
id: "primitive-signed-stock-flow",
98+
name: "Stock and flow with signed links",
99+
description: "Accumulation (stocks) and change (flows), with signed links",
100+
group: "System Dynamics",
101+
},
102+
async () => (await import("./theories/primitive-signed-stock-flow")).default,
103+
);
104+
95105
stdTheories.add(
96106
{
97107
id: "reg-net",
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { ThCategorySignedLinks } from "catlog-wasm";
2+
import { Theory, type TheoryMeta } from "../../theory";
3+
import * as analyses from "../analyses";
4+
import styles from "../styles.module.css";
5+
import svgStyles from "../svg_styles.module.css";
6+
7+
export default function createPrimitiveStockFlowTheory(theoryMeta: TheoryMeta): Theory {
8+
const thCategorySignedLinks = new ThCategorySignedLinks();
9+
10+
return new Theory({
11+
...theoryMeta,
12+
theory: thCategorySignedLinks.theory(),
13+
onlyFreeModels: true,
14+
modelTypes: [
15+
{
16+
tag: "ObType",
17+
obType: { tag: "Basic", content: "Object" },
18+
name: "Stock",
19+
description: "Thing with an amount",
20+
shortcut: ["S"],
21+
cssClasses: [styles.box],
22+
svgClasses: [svgStyles.box],
23+
},
24+
{
25+
tag: "MorType",
26+
morType: {
27+
tag: "Hom",
28+
content: { tag: "Basic", content: "Object" },
29+
},
30+
name: "Flow",
31+
description: "Flow from one stock to another",
32+
shortcut: ["F"],
33+
arrowStyle: "double",
34+
},
35+
{
36+
tag: "MorType",
37+
morType: { tag: "Basic", content: "Link" },
38+
name: "Positive link",
39+
description: "Positive influence of a stock on a flow",
40+
arrowStyle: "plus",
41+
preferUnnamed: true,
42+
shortcut: ["L"],
43+
},
44+
{
45+
tag: "MorType",
46+
morType: { tag: "Basic", content: "NegativeLink" },
47+
name: "Negative link",
48+
description: "Negative influence of a stock on a flow",
49+
arrowStyle: "minus",
50+
preferUnnamed: true,
51+
shortcut: ["K"],
52+
},
53+
],
54+
modelAnalyses: [
55+
analyses.stockFlowDiagram({
56+
id: "diagram",
57+
name: "Visualization",
58+
description: "Visualize the stock and flow diagram",
59+
help: "visualization",
60+
}),
61+
analyses.massAction({
62+
simulate(model, data) {
63+
return thCategorySignedLinks.massAction(model, data);
64+
},
65+
transitionType: {
66+
tag: "Hom",
67+
content: { tag: "Basic", content: "Object" },
68+
},
69+
}),
70+
],
71+
});
72+
}

packages/frontend/src/stdlib/theories/primitive-stock-flow.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { ThCategorySignedLinks } from "catlog-wasm";
1+
import { ThCategoryLinks } from "catlog-wasm";
22
import { Theory, type TheoryMeta } from "../../theory";
33
import * as analyses from "../analyses";
44
import styles from "../styles.module.css";
55
import svgStyles from "../svg_styles.module.css";
66

77
export default function createPrimitiveStockFlowTheory(theoryMeta: TheoryMeta): Theory {
8-
const thCategoryLinks = new ThCategorySignedLinks();
8+
const thCategoryLinks = new ThCategoryLinks();
99

1010
return new Theory({
1111
...theoryMeta,
@@ -34,22 +34,12 @@ export default function createPrimitiveStockFlowTheory(theoryMeta: TheoryMeta):
3434
},
3535
{
3636
tag: "MorType",
37-
morType: { tag: "Basic", content: "PositiveLink" },
38-
name: "Positive link",
39-
description: "Positive influence of a stock on a flow",
40-
arrowStyle: "plus",
37+
morType: { tag: "Basic", content: "Link" },
38+
name: "Link",
39+
description: "Influence of a stock on a flow",
4140
preferUnnamed: true,
4241
shortcut: ["L"],
4342
},
44-
{
45-
tag: "MorType",
46-
morType: { tag: "Basic", content: "NegativeLink" },
47-
name: "Negative link",
48-
description: "Negative influence of a stock on a flow",
49-
arrowStyle: "minus",
50-
preferUnnamed: true,
51-
shortcut: ["K"],
52-
},
5343
],
5444
modelAnalyses: [
5545
analyses.stockFlowDiagram({

0 commit comments

Comments
 (0)