├── .gitignore ├── docs ├── Project.toml ├── src │ └── index.md ├── make.jl └── Manifest.toml ├── src ├── CommonRLSpaces.jl └── basic.jl ├── CITATION.bib ├── .github └── workflows │ ├── TagBot.yml │ ├── register.yml │ ├── CompatHelper.yml │ └── CI.yml ├── Project.toml ├── LICENSE ├── test └── runtests.jl └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.jl.*.cov 2 | *.jl.cov 3 | *.jl.mem 4 | Manifest.toml 5 | /docs/build/ 6 | -------------------------------------------------------------------------------- /docs/Project.toml: -------------------------------------------------------------------------------- 1 | [deps] 2 | CommonRLSpaces = "408f5b3e-f2a2-48a6-b4bb-c8aa44c458e6" 3 | Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" 4 | -------------------------------------------------------------------------------- /src/CommonRLSpaces.jl: -------------------------------------------------------------------------------- 1 | module CommonRLSpaces 2 | 3 | using Reexport 4 | 5 | @reexport using FillArrays 6 | @reexport using IntervalSets 7 | @reexport using StaticArrays 8 | @reexport import Base: OneTo 9 | 10 | include("basic.jl") 11 | 12 | end 13 | -------------------------------------------------------------------------------- /CITATION.bib: -------------------------------------------------------------------------------- 1 | @misc{CommonRLSpaces.jl, 2 | author = {Jun Tian and contributors}, 3 | title = {CommonRLSpaces.jl}, 4 | url = {https://github.com/Jun Tian/CommonRLSpaces.jl}, 5 | version = {v0.1.0}, 6 | year = {2022}, 7 | month = {5} 8 | } 9 | -------------------------------------------------------------------------------- /docs/src/index.md: -------------------------------------------------------------------------------- 1 | ```@meta 2 | CurrentModule = CommonRLSpaces 3 | ``` 4 | 5 | # CommonRLSpaces 6 | 7 | Documentation for [CommonRLSpaces](https://github.com/Jun Tian/CommonRLSpaces.jl). 8 | 9 | ```@index 10 | ``` 11 | 12 | ```@autodocs 13 | Modules = [CommonRLSpaces] 14 | ``` 15 | -------------------------------------------------------------------------------- /.github/workflows/TagBot.yml: -------------------------------------------------------------------------------- 1 | name: TagBot 2 | on: 3 | issue_comment: 4 | types: 5 | - created 6 | workflow_dispatch: 7 | jobs: 8 | TagBot: 9 | if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: JuliaRegistries/TagBot@v1 13 | with: 14 | token: ${{ secrets.GITHUB_TOKEN }} 15 | ssh: ${{ secrets.DOCUMENTER_KEY }} 16 | -------------------------------------------------------------------------------- /.github/workflows/register.yml: -------------------------------------------------------------------------------- 1 | name: Register Package 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | version: 6 | description: Version to register or component to bump 7 | required: true 8 | jobs: 9 | register: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | steps: 14 | - uses: julia-actions/RegisterAction@latest 15 | with: 16 | token: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/CompatHelper.yml: -------------------------------------------------------------------------------- 1 | name: CompatHelper 2 | on: 3 | schedule: 4 | - cron: 0 0 * * * 5 | workflow_dispatch: 6 | jobs: 7 | CompatHelper: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Pkg.add("CompatHelper") 11 | run: julia -e 'using Pkg; Pkg.add("CompatHelper")' 12 | - name: CompatHelper.main() 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} 16 | run: julia -e 'using CompatHelper; CompatHelper.main()' 17 | -------------------------------------------------------------------------------- /Project.toml: -------------------------------------------------------------------------------- 1 | name = "CommonRLSpaces" 2 | uuid = "408f5b3e-f2a2-48a6-b4bb-c8aa44c458e6" 3 | authors = ["Jun Tian and contributors"] 4 | version = "0.1.1" 5 | 6 | [deps] 7 | FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" 8 | IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" 9 | Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 10 | Reexport = "189a3867-3050-52da-a836-e630ba90ab69" 11 | StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" 12 | 13 | [compat] 14 | FillArrays = "0.13" 15 | IntervalSets = "0.7" 16 | Reexport = "1" 17 | StaticArrays = "1" 18 | julia = "1.6" 19 | 20 | [extras] 21 | Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 22 | 23 | [targets] 24 | test = ["Test"] 25 | -------------------------------------------------------------------------------- /docs/make.jl: -------------------------------------------------------------------------------- 1 | using CommonRLSpaces 2 | using Documenter 3 | 4 | DocMeta.setdocmeta!(CommonRLSpaces, :DocTestSetup, :(using CommonRLSpaces); recursive=true) 5 | 6 | makedocs(; 7 | modules=[CommonRLSpaces], 8 | authors="Jun Tian and contributors", 9 | repo="https://github.com/Jun Tian/CommonRLSpaces.jl/blob/{commit}{path}#{line}", 10 | sitename="CommonRLSpaces.jl", 11 | format=Documenter.HTML(; 12 | prettyurls=get(ENV, "CI", "false") == "true", 13 | canonical="https://Jun Tian.github.io/CommonRLSpaces.jl", 14 | assets=String[], 15 | ), 16 | pages=[ 17 | "Home" => "index.md", 18 | ], 19 | ) 20 | 21 | deploydocs(; 22 | repo="github.com/Jun Tian/CommonRLSpaces.jl", 23 | devbranch="main", 24 | ) 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Jun Tian and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/runtests.jl: -------------------------------------------------------------------------------- 1 | using CommonRLSpaces 2 | using Test 3 | 4 | @testset "CommonRLSpaces.jl" begin 5 | @testset "Spaces" begin 6 | s1 = Space((:cat, :dog)) 7 | @test :cat in s1 8 | @test !(nothing in s1) 9 | 10 | s2 = Space(0:1) 11 | @test 0 in s2 12 | @test !(0.5 in s2) 13 | 14 | s3 = Space(Bool) 15 | @test false in s3 16 | @test true in s3 17 | 18 | s4 = Space(Float64) 19 | @test rand() in s4 20 | @test 0 in s4 21 | 22 | s5 = Space(Float64, 3, 4) 23 | @test rand(3, 4) in s5 24 | 25 | s6 = Space(SVector((:cat, :dog), (:litchi, :longan, :mango))) 26 | @test SVector(:dog, :litchi) in s6 27 | 28 | s7 = Space([-1 .. 1, 2 .. 3]) 29 | @test [0, 2] in s7 30 | @test !([-5, 5] in s7) 31 | 32 | for _ in 1:100 33 | for s in [s1, s2, s3, s4, s5, s6, s7] 34 | @test rand(s) in s 35 | end 36 | end 37 | end 38 | 39 | @testset "Meta Spaces" begin 40 | s1 = (Space(1:2), Space(Float64, 2, 3)) 41 | @test (1, rand(2, 3)) in s1 42 | 43 | s2 = (a=Space(1:2), b=Space(Float64, 2, 3)) 44 | @test (a=1, b=rand(2, 3)) in s2 45 | 46 | s3 = Dict(:a => Space(1:2), :b => Space(Float64, 2, 3)) 47 | @test Dict(:a => 1, :b => rand(2, 3)) in s3 48 | 49 | for _ in 1:100 50 | for s in [s1, s2, s3] 51 | rand(s) in s 52 | end 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - main 6 | tags: '*' 7 | pull_request: 8 | concurrency: 9 | # Skip intermediate builds: always. 10 | # Cancel intermediate builds: only if it is a pull request build. 11 | group: ${{ github.workflow }}-${{ github.ref }} 12 | cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} 13 | jobs: 14 | test: 15 | name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | version: 21 | - '1.6' 22 | - '1.7' 23 | - 'nightly' 24 | os: 25 | - ubuntu-latest 26 | arch: 27 | - x64 28 | steps: 29 | - uses: actions/checkout@v2 30 | - uses: julia-actions/setup-julia@v1 31 | with: 32 | version: ${{ matrix.version }} 33 | arch: ${{ matrix.arch }} 34 | - uses: julia-actions/cache@v1 35 | - uses: julia-actions/julia-buildpkg@v1 36 | - uses: julia-actions/julia-runtest@v1 37 | - uses: julia-actions/julia-processcoverage@v1 38 | - uses: codecov/codecov-action@v2 39 | with: 40 | files: lcov.info 41 | docs: 42 | name: Documentation 43 | runs-on: ubuntu-latest 44 | permissions: 45 | contents: write 46 | steps: 47 | - uses: actions/checkout@v2 48 | - uses: julia-actions/setup-julia@v1 49 | with: 50 | version: '1' 51 | - uses: julia-actions/julia-buildpkg@v1 52 | - uses: julia-actions/julia-docdeploy@v1 53 | env: 54 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 55 | - run: | 56 | julia --project=docs -e ' 57 | using Documenter: DocMeta, doctest 58 | using CommonRLSpaces 59 | DocMeta.setdocmeta!(CommonRLSpaces, :DocTestSetup, :(using CommonRLSpaces); recursive=true) 60 | doctest(CommonRLSpaces)' 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CommonRLSpaces 2 | 3 | [![Build Status](https://github.com/JuliaReinforcementLearning/CommonRLSpaces.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/JuliaReinforcementLearning/CommonRLSpaces.jl/actions/workflows/CI.yml?query=branch%3Amain) 4 | [![Coverage](https://codecov.io/gh/JuliaReinforcementLearning/CommonRLSpaces.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/JuliaReinforcementLearning/CommonRLSpaces.jl) 5 | [![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle) 6 | [![PkgEval](https://JuliaCI.github.io/NanosoldierReports/pkgeval_badges/C/CommonRLSpaces.svg)](https://JuliaCI.github.io/NanosoldierReports/pkgeval_badges/report.html) 7 | 8 | ## Usage 9 | 10 | ### Construction 11 | 12 | |Category|Style|Example| 13 | |:---|:----|:-----| 14 | |Enumerable discrete space| `DiscreteSpaceStyle{()}()` | `Space((:cat, :dog))`, `Space(0:1)`, `Space(1:2)`, `Space(Bool)`| 15 | |Multi-dimensional discrete space| `DiscreteSpaceStyle{(3,4)}()` | `Space((:cat, :dog), 3, 4)`, `Space(0:1, 3, 4)`, `Space(1:2, 3, 4)`, `Space(Bool, 3, 4)`| 16 | |Multi-dimensional variable discrete space| `DiscreteSpaceStyle{(2,)}()` | `Space(SVector((:cat, :dog), (:litchi, :longan, :mango))`, `Space([-1:1, (false, true)])`| 17 | |Continuous space| `ContinuousSpaceStyle{()}()` | `Space(-1.2..3.3)`, `Space(Float32)`| 18 | |Multi-dimensional continuous space| `ContinuousSpaceStyle{(3,4)}()` | `Space(-1.2..3.3, 3, 4)`, `Space(Float32, 3, 4)`| 19 | 20 | ### API 21 | 22 | ```julia 23 | julia> using CommonRLSpaces 24 | 25 | julia> s = Space((:litchi, :longan, :mango)) 26 | Space{Tuple{Symbol, Symbol, Symbol}}((:litchi, :longan, :mango)) 27 | 28 | julia> rand(s) 29 | :litchi 30 | 31 | julia> rand(s) in s 32 | true 33 | 34 | julia> size(s) 35 | () 36 | ``` 37 | 38 | ```julia 39 | julia> s = Space(UInt8, 2,3) 40 | Space{Matrix{UnitRange{UInt8}}}(UnitRange{UInt8}[0x00:0xff 0x00:0xff 0x00:0xff; 0x00:0xff 0x00:0xff 0x00:0xff]) 41 | 42 | julia> rand(s) 43 | 2×3 Matrix{UInt8}: 44 | 0x7b 0x38 0xf3 45 | 0x6a 0xe1 0x28 46 | 47 | julia> rand(s) in s 48 | true 49 | 50 | julia> SpaceStyle(s) 51 | DiscreteSpaceStyle{(2, 3)}() 52 | 53 | julia> size(s) 54 | (2, 3) 55 | ``` 56 | 57 | ```julia 58 | julia> s = Space(SVector(-1..1, 0..1)) 59 | Space{SVector{2, ClosedInterval{Int64}}}(ClosedInterval{Int64}[-1..1, 0..1]) 60 | 61 | julia> rand(s) 62 | 2-element SVector{2, Float64} with indices SOneTo(2): 63 | 0.5563101538643473 64 | 0.9227368869418011 65 | 66 | julia> rand(s) in s 67 | true 68 | 69 | julia> SpaceStyle(s) 70 | ContinuousSpaceStyle{(2,)}() 71 | 72 | julia> size(s) 73 | (2,) 74 | ``` -------------------------------------------------------------------------------- /docs/Manifest.toml: -------------------------------------------------------------------------------- 1 | # This file is machine-generated - editing it directly is not advised 2 | 3 | julia_version = "1.7.2" 4 | manifest_format = "2.0" 5 | 6 | [[deps.ANSIColoredPrinters]] 7 | git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" 8 | uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" 9 | version = "0.0.1" 10 | 11 | [[deps.Base64]] 12 | uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" 13 | 14 | [[deps.CommonRLSpaces]] 15 | path = ".." 16 | uuid = "408f5b3e-f2a2-48a6-b4bb-c8aa44c458e6" 17 | version = "0.1.0" 18 | 19 | [[deps.Dates]] 20 | deps = ["Printf"] 21 | uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" 22 | 23 | [[deps.DocStringExtensions]] 24 | deps = ["LibGit2"] 25 | git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b" 26 | uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" 27 | version = "0.8.6" 28 | 29 | [[deps.Documenter]] 30 | deps = ["ANSIColoredPrinters", "Base64", "Dates", "DocStringExtensions", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "REPL", "Test", "Unicode"] 31 | git-tree-sha1 = "3eb46f2549b52a79206469cdc03ae2518ded8d31" 32 | uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" 33 | version = "0.27.18" 34 | 35 | [[deps.IOCapture]] 36 | deps = ["Logging", "Random"] 37 | git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a" 38 | uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" 39 | version = "0.2.2" 40 | 41 | [[deps.InteractiveUtils]] 42 | deps = ["Markdown"] 43 | uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" 44 | 45 | [[deps.JSON]] 46 | deps = ["Dates", "Mmap", "Parsers", "Unicode"] 47 | git-tree-sha1 = "3c837543ddb02250ef42f4738347454f95079d4e" 48 | uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" 49 | version = "0.21.3" 50 | 51 | [[deps.LibGit2]] 52 | deps = ["Base64", "NetworkOptions", "Printf", "SHA"] 53 | uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" 54 | 55 | [[deps.Logging]] 56 | uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" 57 | 58 | [[deps.Markdown]] 59 | deps = ["Base64"] 60 | uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" 61 | 62 | [[deps.Mmap]] 63 | uuid = "a63ad114-7e13-5084-954f-fe012c677804" 64 | 65 | [[deps.NetworkOptions]] 66 | uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" 67 | 68 | [[deps.Parsers]] 69 | deps = ["Dates"] 70 | git-tree-sha1 = "1285416549ccfcdf0c50d4997a94331e88d68413" 71 | uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" 72 | version = "2.3.1" 73 | 74 | [[deps.Printf]] 75 | deps = ["Unicode"] 76 | uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" 77 | 78 | [[deps.REPL]] 79 | deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] 80 | uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" 81 | 82 | [[deps.Random]] 83 | deps = ["SHA", "Serialization"] 84 | uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 85 | 86 | [[deps.SHA]] 87 | uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" 88 | 89 | [[deps.Serialization]] 90 | uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" 91 | 92 | [[deps.Sockets]] 93 | uuid = "6462fe0b-24de-5631-8697-dd941f90decc" 94 | 95 | [[deps.Test]] 96 | deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] 97 | uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 98 | 99 | [[deps.Unicode]] 100 | uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 101 | -------------------------------------------------------------------------------- /src/basic.jl: -------------------------------------------------------------------------------- 1 | export Space, SpaceStyle, DiscreteSpaceStyle, ContinuousSpaceStyle, TupleSpace, NamedSpace, DictSpace 2 | 3 | using Random 4 | 5 | struct Space{T} 6 | s::T 7 | end 8 | 9 | Space(s::Type{T}) where {T<:Number} = Space(typemin(T):typemax(T)) 10 | 11 | Space(x, dims::Int...) = Space(Fill(x, dims)) 12 | Space(x::Type{T}, dim::Int, extra_dims::Int...) where {T<:Integer} = Space(Fill(typemin(x):typemax(T), dim, extra_dims...)) 13 | Space(x::Type{T}, dim::Int, extra_dims::Int...) where {T<:AbstractFloat} = Space(Fill(typemin(x) .. typemax(T), dim, extra_dims...)) 14 | Space(x::Type{T}, dim::Int, extra_dims::Int...) where {T} = Space(Fill(T, dim, extra_dims...)) 15 | 16 | Base.size(s::Space) = size(SpaceStyle(s)) 17 | Base.length(s::Space) = length(SpaceStyle(s), s) 18 | Base.getindex(s::Space, i...) = getindex(SpaceStyle(s), s, i...) 19 | Base.:(==)(s1::Space, s2::Space) = s1.s == s2.s 20 | 21 | ##### 22 | 23 | abstract type AbstractSpaceStyle{S} end 24 | 25 | struct DiscreteSpaceStyle{S} <: AbstractSpaceStyle{S} end 26 | struct ContinuousSpaceStyle{S} <: AbstractSpaceStyle{S} end 27 | 28 | SpaceStyle(::Space{<:Tuple}) = DiscreteSpaceStyle{()}() 29 | SpaceStyle(::Space{<:AbstractVector{<:Number}}) = DiscreteSpaceStyle{()}() 30 | SpaceStyle(::Space{<:AbstractInterval}) = ContinuousSpaceStyle{()}() 31 | 32 | SpaceStyle(s::Space{<:AbstractArray{<:Tuple}}) = DiscreteSpaceStyle{size(s.s)}() 33 | SpaceStyle(s::Space{<:AbstractArray{<:AbstractRange}}) = DiscreteSpaceStyle{size(s.s)}() 34 | SpaceStyle(s::Space{<:AbstractArray{<:AbstractInterval}}) = ContinuousSpaceStyle{size(s.s)}() 35 | 36 | Base.size(::AbstractSpaceStyle{S}) where {S} = S 37 | Base.length(::DiscreteSpaceStyle{()}, s) = length(s.s) 38 | Base.getindex(::DiscreteSpaceStyle{()}, s, i...) = getindex(s.s, i...) 39 | Base.length(::DiscreteSpaceStyle, s) = mapreduce(length, *, s.s) 40 | 41 | ##### 42 | 43 | Random.rand(rng::Random.AbstractRNG, s::Space) = rand(rng, s.s) 44 | 45 | Random.rand( 46 | rng::Random.AbstractRNG, 47 | s::Union{ 48 | <:Space{<:AbstractArray{<:Tuple}}, 49 | <:Space{<:AbstractArray{<:AbstractRange}}, 50 | <:Space{<:AbstractArray{<:AbstractInterval}} 51 | } 52 | ) = map(x -> rand(rng, x), s.s) 53 | 54 | Base.in(x, s::Space) = x in s.s 55 | Base.in(x, s::Space{<:Type}) = x isa s.s 56 | 57 | Base.in( 58 | x, 59 | s::Union{ 60 | <:Space{<:AbstractArray{<:Tuple}}, 61 | <:Space{<:AbstractArray{<:AbstractRange}}, 62 | <:Space{<:AbstractArray{<:AbstractInterval}} 63 | } 64 | ) = size(x) == size(s) && all(x -> x[1] in x[2], zip(x, s.s)) 65 | 66 | function Random.rand(rng::AbstractRNG, s::Interval{:closed,:closed,T}) where {T} 67 | if s == typemin(T) .. typemax(T) 68 | rand(T) 69 | else 70 | r = rand(rng) 71 | 72 | if r == 0.0 73 | r = rand(Bool) 74 | end 75 | 76 | r * (s.right - s.left) + s.left 77 | end 78 | end 79 | 80 | Base.iterate(s::Space, args...) = iterate(SpaceStyle(s), s, args...) 81 | Base.iterate(::DiscreteSpaceStyle{()}, s::Space, args...) = iterate(s.s, args...) 82 | 83 | ##### 84 | 85 | const TupleSpace = Tuple{Vararg{Space}} 86 | const NamedSpace = NamedTuple{<:Any,<:TupleSpace} 87 | const VectorSpace = Vector{<:Space} 88 | const DictSpace = Dict{<:Any,<:Space} 89 | 90 | Random.rand(rng::AbstractRNG, s::Union{TupleSpace,NamedSpace,VectorSpace}) = map(x -> rand(rng, x), s) 91 | Random.rand(rng::AbstractRNG, s::DictSpace) = Dict(k => rand(rng, s[k]) for k in keys(s)) 92 | 93 | Base.in(xs::Tuple, ts::TupleSpace) = length(xs) == length(ts) && all(((x, s),) -> x in s, zip(xs, ts)) 94 | Base.in(xs::AbstractVector, ts::VectorSpace) = length(xs) == length(ts) && all(((x, s),) -> x in s, zip(xs, ts)) 95 | Base.in(xs::NamedTuple{names}, ns::NamedTuple{names,<:TupleSpace}) where {names} = all(((x, s),) -> x in s, zip(xs, ns)) 96 | Base.in(xs::Dict, ds::DictSpace) = length(xs) == length(ds) && all(k -> haskey(ds, k) && xs[k] in ds[k], keys(xs)) --------------------------------------------------------------------------------