Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Causal Loop with Polarities #128

Merged
merged 77 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
2922dca
Added composition for causal loop. Temporarily swapped polarities to…
neonWhiteout Mar 19, 2024
ee19112
Restored Polarities to be an enum instead of Symbol. Updated causal …
neonWhiteout Mar 20, 2024
eb77d69
Added a one-line Causal Loop DSL, similar to feet. Invoked via @cl
neonWhiteout Apr 15, 2024
cac81b2
Edits to Composition DSL to also work with CausalLoopF
neonWhiteout Apr 25, 2024
366d0fb
Fixed enames to provide the symbols for the nodes instead of the indi…
neonWhiteout Apr 25, 2024
dbe737c
Added two simple tests for causal loop composition
neonWhiteout Apr 25, 2024
63d72d7
export create_foot and cl_macro from Syntax
neonWhiteout Apr 25, 2024
7292b32
Updated causal loop tests to reflect new syntax
neonWhiteout May 3, 2024
c194530
Updated another test's syntax to reflect new causal loop syntax
neonWhiteout May 3, 2024
66b88ee
Removed some commented out code
neonWhiteout May 10, 2024
52ab674
Change Graph to GraphSF to not interfere with Catlab Graph.
neonWhiteout May 10, 2024
cb1d355
Replace Graph with GraphSF in visualization tests
neonWhiteout May 11, 2024
6fa1ee6
Eliminate third nested for loop in extract loops with calls to incident
neonWhiteout May 24, 2024
432218b
Split cycle detection into its own function
neonWhiteout May 24, 2024
f4d7d94
Define operations on polarities and rewrite extract_loops to use a foldl
neonWhiteout May 24, 2024
bde5b0d
Polarity operations. is_walk and is_circuit functions.
neonWhiteout May 24, 2024
0e19b0c
Began work to migrate over to newly defined causal loop schema
neonWhiteout Jun 2, 2024
8148ac2
Merge branch 'GraphFix' into SemanticDomainsRough
neonWhiteout Jun 3, 2024
7ab54c5
Merge branch 'CausalLoopCompose' into SemanticDomainsRough; Introduce…
neonWhiteout Jun 6, 2024
d6a6cc0
Add function to extract all paths with nonduplicated nodes
neonWhiteout Jun 8, 2024
455751b
Began testing on causal loop functions
neonWhiteout Jun 10, 2024
ba211fc
Begin work on composition for new causal loop schemas. Update projec…
neonWhiteout Jun 13, 2024
f642d07
Added stockflow migration to cl
neonWhiteout Jun 13, 2024
484c9b7
Composition for CausalLoopPM
neonWhiteout Jun 14, 2024
68f1d29
Fix visualization with CL; replace balancing and reinforcing with pos…
neonWhiteout Jun 17, 2024
abd1055
Removed dangling CausalLoopF()
neonWhiteout Jun 18, 2024
7332a55
Export betweenness
neonWhiteout Jun 27, 2024
69017cd
Added some tests for CausalLoop.jl
neonWhiteout Jul 4, 2024
cdb52ad
Update tests
neonWhiteout Jul 19, 2024
74bb6d3
Further cl tests
neonWhiteout Jul 21, 2024
f722839
Shortest path, number of inputs/outputs for each node, further tests.
neonWhiteout Jul 24, 2024
87ec2dc
Remove Data Migrations requirement
neonWhiteout Jul 24, 2024
e37fbfe
Merge branch 'main' into SemanticDomainsNoZero
neonWhiteout Jul 24, 2024
e4f6bda
Remove lines in Syntax that refer to zero, unknown and not well defin…
neonWhiteout Jul 24, 2024
495f024
Removed reference to nonstandard polarities in tests
neonWhiteout Jul 24, 2024
b4a7d4b
Add ReTestItems as extra dependency. Begin adding docstrings. Creat…
neonWhiteout Jul 28, 2024
c475ee6
Finish adding docstrings for all causal loop functions.
neonWhiteout Jul 29, 2024
750578c
Fixed pname vector type; use Vector Tuple instead of Vector Pair.
neonWhiteout Jul 29, 2024
c301c9a
Merge remote-tracking branch 'origin/main' into SemanticDomainsNoZero
neonWhiteout Jul 29, 2024
8ea84d2
Revert to using testset
neonWhiteout Jul 29, 2024
21143d0
Use GraphCL to graph causal loop diagrams.
neonWhiteout Jul 29, 2024
b79fdaf
Fix visualization tests
neonWhiteout Jul 29, 2024
443601b
Fix visualization tests. Edit some causal loop functions to now retu…
neonWhiteout Jul 29, 2024
2e1e0dd
Update Project.toml
neonWhiteout Jul 29, 2024
b20a51f
Remove GraphSF
neonWhiteout Jul 29, 2024
c3045ff
Merge branch 'SemanticDomainsNoZero' of github.com:neonWhiteout/Stock…
neonWhiteout Jul 29, 2024
b5fad84
Fix documentation causal loop example using Graph instead of GraphCL
neonWhiteout Jul 29, 2024
b44a51d
nv -> nvert
neonWhiteout Jul 29, 2024
5fdce06
nname -> vname
neonWhiteout Jul 29, 2024
dd67909
Re-add sedge and tedge for CausalLoop
neonWhiteout Jul 29, 2024
0333011
Add docstrings to cl macros in Syntax.
neonWhiteout Aug 1, 2024
28c5bc6
Update visualization GraphRB; add docstrings to causal loop visualiza…
neonWhiteout Aug 1, 2024
f29cc28
Recombine GraphRB functions; rename Graph_RB -> GraphRB in visualizat…
neonWhiteout Aug 1, 2024
70635a0
Update types accepted for is_walk and is_circuit
neonWhiteout Aug 1, 2024
f8e2c75
Remove failing test (GraphViz node acting weird)
neonWhiteout Aug 1, 2024
f3357d5
Replace nnames export with vnames
neonWhiteout Aug 1, 2024
c83b21c
Allow creating cl without polarities using @cl macro. Add functions …
neonWhiteout Aug 2, 2024
468b6f5
Began adding shortest path checks. Actually check the list of nodes …
neonWhiteout Aug 2, 2024
03ab046
Add tests for all_shortest_paths
neonWhiteout Aug 2, 2024
91163a5
Add a few betweenness tests; remove export of shortest_path
neonWhiteout Aug 3, 2024
2760aa3
Additional betweeness tests.
neonWhiteout Aug 3, 2024
f1bfc47
Betweenness returns a vector of rationals, rather than a float, to pr…
neonWhiteout Aug 3, 2024
397d084
Fix error in converting CausalLoopPM to CausalLoop. Rewrite all_shor…
neonWhiteout Aug 6, 2024
a9438ee
Remove show all_paths
neonWhiteout Aug 6, 2024
379c5c9
Fix typo in all_shortest_paths causing miscalculation of len(A -> B -…
neonWhiteout Aug 6, 2024
0824cd5
Redid all_shortest_paths, more brief
neonWhiteout Aug 6, 2024
5498a07
Redo all_shortest_paths again, using adjacency matrix.
neonWhiteout Aug 6, 2024
849035a
Added jupyter file and corresponding .jl for causal loop operations.
neonWhiteout Aug 6, 2024
0d851c1
Causal -> Casual in make.jl, to keep folder names consistent.
neonWhiteout Aug 6, 2024
77de7c7
Further shortest path tests
neonWhiteout Aug 13, 2024
1582ce7
Update runtests.jl
neonWhiteout Aug 13, 2024
cfe4749
Update DSL.md. Remove homomorphism (hasn't merged), add causal_loop …
neonWhiteout Aug 13, 2024
4dcde84
Merge branch 'SemanticDomainsNoZero' of github.com:neonWhiteout/Stock…
neonWhiteout Aug 13, 2024
d679f4b
"Add documentation for causal loop composition, modify composition to…
neonWhiteout Aug 13, 2024
3ac08f3
Edit composition so sfcompose is multiple functions, instead of check…
neonWhiteout Aug 14, 2024
acd90c9
Merge branch 'main' into SemanticDomainsNoZero. Increment Project.to…
neonWhiteout Aug 18, 2024
19ee94f
Fix Syntax tests for 0.2.2
neonWhiteout Aug 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name = "StockFlow"
uuid = "58c4a0e8-2944-4d18-9fa2-e17726aee9e5"
license = "MIT"
authors = ["Xiaoyan Li <[email protected]>"]
version = "0.2.1"
version = "0.2.2"

[deps]
AlgebraicRewriting = "725a01d3-f174-5bbd-84e1-b9417bad95d9"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# # Causal Loop Operations

using StockFlow
using StockFlow.Syntax
using StockFlow.PremadeModels

GraphCL(convertToCausalLoop(seir()))

C2 = CausalLoopPM([:C2], [:C2 => :C2 for _ in 1:5], [POL_NEGATIVE, POL_POSITIVE, POL_NEGATIVE, POL_POSITIVE, POL_NEGATIVE])

C2′ = @causal_loop begin
:nodes
C2
:edges
C2 => -C2
C2 => +C2
C2 => -C2
C2 => +C2
C2 => -C2
end;

C2′′ = (@cl C2 => -C2, C2 => +C2, C2 => -C2, C2 => +C2, C2 => -C2);

C2 == C2′ == C2′′

GraphCL(C2)

GraphRB(C2)

CL_ABC = @cl A => +B, B => +C, C => -A, D

GraphCL(CL_ABC)

GraphRB(CL_ABC)

nvert(CL_ABC)

nedges(CL_ABC)

np(CL_ABC)

nm(CL_ABC)

sedge(CL_ABC, 3) # Source node for edge 3, which is C => A, is C, which is index 3

tedge(CL_ABC, 3) # C => A, target is A, with index 1

vnames(CL_ABC)

epol(CL_ABC, 1) # Polarity of edge 1, A => B, is positive

epols(CL_ABC)

outgoing_edges(CL_ABC, 1) # indices of all edges with src 1 (in this case, A)

outgoing_edges(CL_ABC, 4) # D

incoming_edges(CL_ABC, 1) # indices of all edges with src 1

cl_cycles(CL_ABC)

extract_loops(CL_ABC)

is_walk(CL_ABC, [1,2,3,1,2])

is_walk(CL_ABC, [3,2])

is_walk(CL_ABC, Vector{Int}())

is_circuit(CL_ABC, [1,2,3])

is_circuit(CL_ABC, [1,2])

walk_polarity(CL_ABC, [1,2,3,1,2,3])

extract_all_nonduplicate_paths(CL_ABC)

num_loops_var_on(CL_ABC, :D)

num_loops_var_on(CL_ABC, :A)

num_loops_var_on(C2, :C2)

num_indep_loops_var_on(C2, :C2) # Treating each pair of nodes as if there is at most one edge between them

to_graphs_graph(CL_ABC)

betweenness(CL_ABC)

to_graphs_graph(C2) # eliminates duplicate edges!

betweenness(C2)

num_inputs_outputs(C2) # in, out

num_inputs_outputs_pols(C2) # pos in, pos out, neg in, neg out

all_shortest_paths(C2)

all_shortest_paths(@cl((A => B, B => C, C => D, A => B′, B′ => C′, C′ => D)))

shortest_paths( (@cl A => B, B => C, C => D, A => B′, B′ => C′, C′ => D), :A, :D )

betweenness(@cl((A => B, B => C, C => D, A => B′, B′ => C′, C′ => D)))

all_shortest_paths(convertToCausalLoop(seir()))

all_shortest_paths(CL_ABC)

GraphCL(CL_ABC)

shortest_paths(CL_ABC, :A, :C)

cl = @causal_loop begin
:nodes
A
B
C
D
E
:edges
A => B
B => C
B => C
B => D
D => C
end;

cl2 = @causal_loop begin
:nodes
A
B
C
D
E
:edges
A => B
B => C
B => D
D => C
end;

GraphCL(cl)

betweenness(cl)

betweenness(cl2)

# ### Note, negative polarities always come after positive!

cl_small = @cl A => -B, B => +C

epols(cl_small)

to_simple_cl(cl_small) == (@cl A, B => C, A => B) # Note the order!

to_simple_cl(cl_small)

using StockFlow.Syntax.Composition

ABC = (@cl A => B, B => C)
BCD = (@cl B => C, C => D)
@compose ABC BCD begin
(ABC, BCD)
(ABC, BCD) ^ B => C
end

ABC_pol = (@cl A => +B, B => -C)
BCD_pol = (@cl B => -C, C => +D)
@compose ABC_pol BCD_pol begin
(ABC, BCD)
(ABC, BCD) ^ B => -C
end

Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ GraphF(seir)

seir_causalLoop = convertToCausalLoop(seir)

Graph(seir_causalLoop)
GraphCL(seir_causalLoop)


1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ makedocs(
"Example" => Any[
"generated/Covid19_composition_model_in_paper.md",
"generated/full_fledged_schema_examples_new/CasualLoopDiagrams/convert_from_SEIR_stockFlowDiagram.md",
"generated/full_fledged_schema_examples_new/CasualLoopDiagrams/Causal_Loop_Operations.md",
"generated/full_fledged_schema_examples_new/composition/composed_open_population_SIRV_model.md",
"generated/full_fledged_schema_examples_new/composition/COVID_full_model.md",
"generated/full_fledged_schema_examples_new/composition/curable_sexually_transmitted_diseases_model.md",
Expand Down
142 changes: 109 additions & 33 deletions docs/src/DSLs.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,100 @@ end) == ([StockAndFlow0([:A, :AA],[:B],[:A => :B, :AA => :B]),
StockAndFlow0([:X, :Z],[:Y, :B],[:X => :Y, :X => :B])])
```

---

---

## @causal_loop

Create a causal loop, with or without polarities. X => +Y indicates a positive
polarity, X => -Y indicates a negative polarity, and if there are any edges
X => Y without polarities, the ultimate causal loop diagram will be without
polarities.

Use :nodes to indicate nodes, and :edges to indicate edges.

If there are no edges, will default to a causal loop with polarities.

Note, for functions which return indices for edges, negative edges come
after positive edges.

Avoid using nodes with the same name.

```julia

# Triangle, without polarities.
@causal_loop begin
:nodes
A
B
C

:edges
A => B
B => C
C => A
end

# Triangle, with polarities, creating a balancing loop.
@causal_loop begin
:nodes
A
B
C

:edges
A => -B
B => +C
C => +A
end

# Causal loop with two nodes and three edges;
# A has a positive self edge, and A has two edges to B, one positive, one negative.
@causal_loop begin
:nodes
A
B

:edges
A => +A
A => +B
A => -B
end

# Empty causal loop, treated with polarities.
@causal_loop begin end

```

---

## @cl

Compressed syntax for creating a causal loop diagram. Similar to above.

Separate statements with commas, and use a symbol on its own to indicate a
node without an edge. Nodes will be ordered in the order they're encountered.

```julia
# Triangle, without polarities.
(@cl A => B, B => C, C => A)
# Triangle, with polarities, creating a balancing loop.
(@cl A => -B, B => +C C => +A)

# No edges between nodes, treated as a causal loop with polarities.
(@cl A, B, C)

# Same as first, but now C is node 1, B is node 2, and A is node 3.
(@cl C, B, A => B, B => C, C => A)

# Empty causal loop, treated as with polarities.
(@cl)

```



---

# Stratification
Expand Down Expand Up @@ -261,6 +355,10 @@ and sums which are in the corresponding foot.

Composition with no stockflows given as argument returns an empty stockflow.

Composition also works with causal loop diagrams. If using causal loop with
polarities, the edges you compose on must have the same polarities; you
cannot compose A => +B with A => -B.

```julia
(@compose begin
()
Expand All @@ -287,6 +385,15 @@ Diabetes_Model = @compose Model_Normoglycemic Model_Hyperglycemic Model_Norm_Hyp
(Hyper, NH) ^ Prediabetic_U => N
(Hyper, NH) ^ Prediabetic_D => N
end

ABC = (@cl A => B, B => C)
BCD = (@cl B => C, C => D)

ABCD = @compose ABC BCD begin
(ABC, BCD)
(ABC, BCD) ^ B => C
end

```

---
Expand All @@ -306,10 +413,10 @@ Rewrite has 8 headers, :stocks, :flows, :sums, :dynamic\_variables, :redefs, :re
and :dyvar\_swaps

The first five are used to indicate if an instance of that type is being
added. Use the same definition syntax as in @stock_and_flow.
added. Use the same definition syntax as in @stock\_and\_flow.

:redefs is used to change the definition of a dynamic variable, flow or
sum. Again, use the same syntax as in @stock_and_flow.
sum. Again, use the same syntax as in @stock\_and\_flow.

:removes indicates that an object should be deleted. You just need the name of it in the original.

Expand Down Expand Up @@ -370,39 +477,8 @@ end

---

# Homomorphism

## @hom

Using two stockflows and a block with the same headers as @stratify, define an ACSetTransformation from the first stockflow to another.

Half of a stratify. Rather than creating two homomorphisms and taking the pullback, creates one homomorphism.

```julia
@hom WeightModel l_type begin
:stocks
NormalWeight => pop
OverWeight => pop
Obese => pop

:parameters
μ => μ
~δ => δ
rage => rage
_ => rFstOrder

:dynamic_variables
v_NewBorn => v_birth
~Becoming => v_fstOrder
~Death => v_death
_ => v_aging

:flows
f_NewBorn => f_birth
~Becoming => f_fstOrder
~Death => f_death
~id => f_aging
_ => f_death

end
```
Loading
Loading