Skip to content

Commit

Permalink
foo
Browse files Browse the repository at this point in the history
  • Loading branch information
neonWhiteout committed Sep 1, 2023
1 parent 6550b3e commit 7632f69
Showing 1 changed file with 0 additions and 206 deletions.
206 changes: 0 additions & 206 deletions test/Syntax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -341,209 +341,3 @@ end
@test_throws Exception @eval @feet begin A => B; 1 => 2; end
end

###########################

@testset "infer_links works as expected" begin
# No prior mappings means no inferred mappings
@test (infer_links(StockAndFlowF(), StockAndFlowF(), Dict{Symbol, Vector{Int64}}(:S => [], :F => [], :SV => [], :P => [], :V => []))
== Dict(:LS => [], :LSV => [], :LV => [], :I => [], :O => [], :LPV => [], :LVV => []))

# S: 1 -> 1 and SV: 1 -> 1 implies LS: 1 -> 1
@test (infer_links(
(@stock_and_flow begin; :stocks; A; :sums; NA = [A]; end),
(@stock_and_flow begin; :stocks; B; :sums; NB = [B]; end),
Dict{Symbol, Vector{Int64}}(:S => [1], :F => [], :SV => [1], :P => [], :V => []))
== Dict(:LS => [1], :LSV => [], :LV => [], :I => [], :O => [], :LPV => [], :LVV => []))

# annoying exanmple, required me to add code to disambiguate using position
# that is, vA = A + A, vA -> vB, A -> implies that the As in the vA definition map to the Bs in the vB definition
# But both As link to the same stock and dynamic variable so just looking at those isn't enough to figure out what it maps to.
# There will exist cases where it's impossible to tell - eg, when there exist multiple duplicate links, and some positions don't match up.

# It does not currently look at the operator. You could therefore map vA = A + A -> vB = B * B
# I can see this being useful, actually, specifically when mapping between + and -, * and /, etc. Probably logs and powers too.
# Just need to be aware that it won't say it's invalid.
@test (infer_links(
(@stock_and_flow begin; :stocks; A; :dynamic_variables; vA = A + A; end),
(@stock_and_flow begin; :stocks; B; :dynamic_variables; vB = B + B; end),
Dict{Symbol, Vector{Int64}}(:S => [1], :F => [], :SV => [], :P => [], :V => [1]))
== Dict(:LS => [], :LSV => [], :LV => [2,2], :I => [], :O => [], :LPV => [], :LVV => [])) # If duplicate values, always map to end.

@test (infer_links(
(@stock_and_flow begin; :stocks; A; :parameters; pA; :dynamic_variables; vA = A + pA; end),
(@stock_and_flow begin; :stocks; B; :parameters; pB; :dynamic_variables; vB = pB + B; end),
Dict{Symbol, Vector{Int64}}(:S => [1], :F => [], :SV => [], :P => [1], :V => [1]))
== Dict(:LS => [], :LSV => [], :LV => [1], :I => [], :O => [], :LPV => [1], :LVV => []))

@test (infer_links(
(@stock_and_flow begin
:stocks
S
I
R

:parameters
p_inf
p_rec


:flows
S => f_StoI(p_inf * S) => I
I => f_ItoR(I * p_rec) => R

:sums
N = [S,I,R]
NI = [I]
NS = [S,I,R]
end),
(@stock_and_flow begin
:stocks
pop

:parameters
p_generic


:flows
pop => f_generic(p_generic * pop) => pop

:sums
N = [pop]
NI = [pop]
NS = [pop]
end),

Dict{Symbol, Vector{Int64}}(:S => [1,1,1], :F => [1,1], :SV => [1,2,3], :P => [1,1], :V => [1,1]))
== Dict(:LS => [1,3,1,2,3,1,3], :LSV => [], :LV => [1,1], :I => [1,1], :O => [1,1], :LPV => [1,1], :LVV => []))


end


@testset "Applying flags can correctly find substring matches" begin
@test apply_flags(:f_, Set([:~]), Vector{Symbol}()) == []
@test apply_flags(:f_, Set([:~]), [:f_death, :f_birth]) == [:f_death, :f_birth]
@test apply_flags(:NOMATCH, Set([:~]), [:f_death, :f_birth]) == []
@test apply_flags(:f_birth, Set([:~]), [:f_death, :f_birth]) == [:f_birth]
@test apply_flags(:f_birth, Set{Symbol}(), [:f_death, :f_birth]) == [:f_birth]

# Note, apply_flags is specifically meant to work on vectors without duplicates; the vector which is input are the keys of a dictionary.
# Regardless, the following will hold:
@test apply_flags(:f_birth, Set{Symbol}(), [:f_death, :f_birth, :f_birth, :f_birth]) == [:f_birth]
@test apply_flags(:f_birth, Set{Symbol}([:~]), [:f_death, :f_birth, :f_birth, :f_birth]) == [:f_birth, :f_birth, :f_birth]
end


@testset "substitute_symbols will correctly associate values of the two provided dictionaries based on user defined mappings" begin
# substitute_symbols(s::Dict{Symbol, Int}, t::Dict{Symbol, Int}, m::Vector{DSLArgument} ; use_flags::Bool=true)::Dict{Int, Int}


# Note, these dictionaries represent a vector where all the entries are unique, and the values are the original indices.
# So, both keys and values should be unique.
# For stratification, first dictionary is strata or aggregate, second is type, and the vector of DSLArgument are the user-defined maps.
# For homomorphism, first argument is src, second is dest, vector are user-defined maps.
@test substitute_symbols(Dict{Symbol, Int}(), Dict{Symbol, Int}(), Vector{DSLArgument}()) == Dict{Int, Int}()
@test substitute_symbols(Dict{Symbol, Int}(), Dict(:B => 2), Vector{DSLArgument}()) == Dict{Int, Int}()

@test substitute_symbols(Dict(:A => 1), Dict(:B => 1), [DSLArgument(:A, :B, Set{Symbol}())]) == Dict(1 => 1)
@test substitute_symbols(Dict(:A1 => 1, :A2 => 2), Dict(:B => 1), [DSLArgument(:A1, :B, Set{Symbol}()), DSLArgument(:A2, :B, Set{Symbol}())]) == Dict(1 => 1, 2 => 1)
@test substitute_symbols(Dict(:A1 => 1), Dict(:B1 => 1, :B2 => 2), [DSLArgument(:A1, :B2, Set{Symbol}())]) == Dict(1 => 2)


@test substitute_symbols(Dict(:A1 => 1, :A2 => 2), Dict(:B1 => 1, :B2 => 2), [DSLArgument(:A, :B2, Set{Symbol}([:~]))]) == Dict(1 => 2, 2 => 2)

# 1:100
# 1:50
# All multiples x of 14 below 100 go to x % 10 + 1
@test (substitute_symbols(Dict(Symbol(i) => i for i 1:100), Dict(Symbol(-i) => i for i 1:50), [DSLArgument(Symbol(i), Symbol(-((i%10) + 1)), Set{Symbol}()) for i 1:100 if i % 14 == 0])
== Dict(14 => 5, 28 => 9, 42 => 3, 56 => 7, 70 => 1, 84 => 5, 98 => 9))

# Captures everything with a 7 as a digit
@test (substitute_symbols(Dict(Symbol(i) => i for i 1:100), Dict(Symbol(-i) => i for i 1:50), [DSLArgument(Symbol(7), Symbol(-1), Set{Symbol}([:~]))])
== Dict(7 => 1, 17 => 1, 27 => 1, 37 => 1, 47 => 1, 57 => 1, 67 => 1, 70 => 1, 71 => 1, 72 => 1, 73 => 1, 74 => 1, 75 => 1, 76 => 1, 77 => 1, 78 => 1, 79 => 1, 87 => 1, 97 => 1))

@test substitute_symbols(Dict(Symbol("~") => 1), Dict(:R => 1), [DSLArgument(Symbol("~"), :R, Set([:~]))], ; use_flags = false) == Dict(1 => 1) # Note, the Set([:~]) is ignored because use_flags is false

end


@testset "non-natural transformations fail infer_links" begin

# Map both dynamic variables to the same
# Obviously, this will fail, as the new dynamic variable needs a LVV and one LV, but instead has two LV
@test_throws KeyError (infer_links(
(@stock_and_flow begin
:stocks
A

:dynamic_variables
v1 = A + A
v2 = v1 + A
end),
(@stock_and_flow begin
:stocks
A

:dynamic_variables
v1 = A + A
end),
Dict{Symbol, Vector{Int64}}(:S => [1], :V => [1,1])))



# Mapping it all to I

# This one fails when trying to figure out the inflow. Stock maps to 2, and flow maps to 2,
# But inflows on the target have (1,2) and (2,3)

# This also wouldn't work if we tried mapping flow to 1 instead. Outflows expect 1,1 or 2,2,
# so it fails on (2,1).
@test_throws KeyError (infer_links(
(@stock_and_flow begin
:stocks
pop

:parameters
p_generic


:flows
pop => f_generic(p_generic * pop) => pop

:sums
N = [pop]
NI = [pop]
NS = [pop]
end),
(@stock_and_flow begin
:stocks
S
I
R

:parameters
p_inf
p_rec


:flows
S => f_StoI(p_inf * S) => I
I => f_ItoR(I * p_rec) => R

:sums
N = [S,I,R]
NI = [I]
NS = [S,I,R]
end),
Dict{Symbol, Vector{Int64}}(:S => [2], :F => [2], :SV => [1,2,3], :P => [2], :V => [2])))

end

@testset "Applying flags throws on invalid inputs" begin
@test_throws ErrorException apply_flags(:f_, Set([:+]), [:f_death, :f_birth]) # fails because :+ is not a defined operation
@test_throws ErrorException apply_flags(:f_birth, Set([:~, :+]), [:f_death, :f_birth]) # also fails for same reason

@test_throws AssertionError apply_flags(:NOMATCH, Set{Symbol}(), Vector{Symbol}()) # fails because it's not looking for substrings, and :NOMATCH isn't in the list of options.
@test_throws AssertionError apply_flags(:NOMATCH, Set{Symbol}(), [:nomatch]) # same reason

end

0 comments on commit 7632f69

Please sign in to comment.