In case it is of any interest, I have prepared a demographic model (MiniDemographicABM.jl) which is quite an abstract dummy version of a more sophisticated model. It works fine.
The space type is simply a vector of towns (which implicitly includes all houses and their occupants, i.e. the whole population of agents). Agent::pos is a house type. There is no syntax constraint between agent::pos and model::space (except the logic needs to make sense).
Edit: to summarise, the basic types were as follows:
struct House{TownType,PersonType}
town::TownType
location::NTuple{2,Int}
occupants::Vector{PersonType}
...
end
..
struct TownH{HouseType}
name::String
density::Float64
location::NTuple{2,Int}
houses::Vector{HouseType}
end
...
mutable struct PersonH{HouseType} <: AbstractAgent
const id::Int
pos::HouseType
..
end
...
const Town = TownH{HouseTP}
const House = HouseTP{Town,PersonH}
const Person = PersonH{House}
...
abstract type PopulationSpace <: Agents.DiscreteSpace end
struct DemographicMap <: PopulationSpace
countryname::String
maxTownGridDim::Int
towns::Vector{Town}
end
...
const DemographicABM = ABM{DemographicMap}
DemographicABM(space::DemographicMap, props::DemographicABMProp) =
ABM(Person, space; properties = props)