abstract type AbstractProposal end rand(rng::AbstractRNG, p::AbstractProposal) = rand(Random.default_rng(), p) propose(rng::AbstractRNG, p::AbstractProposal, x=nothing) = propose(rng, p, x) propose(rng::AbstractRNG, p::AbstractProposal, x::Nothing) = rand(rng, p) logpratio(p::AbstractProposal, x, y) = 0 # symmetric proposal by default struct RandomWalk{I, S, F} <: AbstractProposal init :: I step :: S func :: F end RandomWalk(init::Distribution, step::Distribution) = RandomWalk(init, step, (.+)) rand(rng::AbstractRNG, p::RandomWalk{<:Distribution, <:Any}) = rand(rng, p.init) propose(rng::AbstractRNG, p::RandomWalk{<:Distribution, <:Distribution}, x) = p.func(x, rand(rng, p.step)) function CyclicWalk(a=-1, b=1, s=.5) init = Uniform(a,b); step = Uniform(-s, s) func = (x,y) -> mod(x+y - a, b-a) + a RandomWalk(init, step, func) end include("networks.jl")