text:
@testset "@when" begin
    @testset "docstring" begin
        # otherwise()
        @test 3 == @when (a, b) = (1, 2) begin
            a + b
        @otherwise
            0
        end
        @test 0 == @when (a, b) = () begin
            a + b
        @otherwise
            0
        end

        # macro when
        @test (1,2,3) == @when let (a, 1) = (1, 1),
                                   [b, c, 5] = [2, 3, 5]
            (a, b, c)
        end

        x = 1
        @test :int == @when let (_, _) = x
            :tuple
        @when begin ::Float64 = x end
            :float
        @when ::Int = x
            :int
        @otherwise
            :unknown
        end

        x = 1
        y = (1, 2)
        cond1 = true
        cond2 = true
        @test 3 == @when let cond1.?,
                  (a, b) = x
            a + b
        @when begin if cond2 end
                    (a, b) = y
              end
            a + b
        end
    end

    @testset "Only @when" begin
        @test 2 == @when let (a, 1) = (2, 1)
            a
        end
        @test 2 == @when (a, 1) = (2, 1) a

        @test 2 === @when let 1 = 1
            2
        end
        @test 2 === @when 1 = 1 2

        @test 1 === @when let a = 1
            a
        end
        @test 1 === @when a = 1 a

        @test nothing === @when let (a, b) = 1
            a + b
        end
        @test nothing === @when (a, b) = 1 a + b

        ab = (2, 3)
        @test 5 === @when let (a, b) = ab
            a + b
        end
        @test 5 === @when (a, b) = ab a + b
    end

    @testset "@when + @data" begin
        @data WhenTest begin
            WhenTest_1(Int)
            WhenTest_2(Int)
        end

        var1 = WhenTest_1(2)
        var2 = WhenTest_2(2)
        @test 200 === @when let WhenTest_1(x) = var1,
                                @inline WhenAction(x) = 100x
            WhenAction(x)
        end

        @test 200 === @when WhenTest_1(x) = var1 begin
            100x
        end

        @test nothing === @when let WhenTest_1(x) = var2,
                                    @inline WhenAction(x) = 100x
            WhenAction(x)
        end
    end

    @testset "when with predicates" begin
        @test 2 === @when let if 1 > 0 end
            2
        end
        @test 3 === @when let (a, b) = (1, 2),
                              (1 > 0).?
                a + b
        end
    end

    @testset "@when in @when" begin
        function f1(args...)
            x = Tuple(args)
            @when (a, 1) = x begin
                a
            @when (b, 2) = x
                (2, b)
            end
        end
        # case: a
        @test f1(111, 1) == 111
        @test f1(222, 1) == 222
        # case: (2, b)
        @test f1(111, 2) == (2, 111)
        @test f1(222, 2) == (2, 222)
        # default case
        @test f1() == nothing

        function f2(args...)
            x = Tuple(args)
            @when (a, 1) = x begin
                a
            @when (b, 2) = x
                (:b, b)
            @when (c, 3) = x
                (:c, c)
            end
        end
        @test f2(10, 1) == 10       # case: a
        @test f2(20, 2) == (:b, 20) # case: (:b, b)
        @test f2(30, 3) == (:c, 30) # case: (:c, c)
        @test f2() == nothing       # default case
    end

    @testset "@when + @otherwise" begin
        function f1(args...)
            x = Tuple(args)
            @when (a, 1) = x begin
                a
            @otherwise
                x
            end
        end
        @test f1(1) == (1, )        # case: x
        @test f1(1, 2) == (1, 2)    # case: x
        @test f1(2, 1) == 2         # case: a

        function f2(args...)
            x = Tuple(args)
            @when (a, 1) = x begin
                a
            @when (b, 2) = x
                (:b, b)
            @when (c, 3) = x
                (:c, c)
            @otherwise
                x
            end
        end
        @test f2(1) == (1, )        # case: x
        @test f2(1, 0) == (1, 0)    # case: x
        @test f2(10, 1) == 10       # case: a
        @test f2(20, 2) == (:b, 20) # case: (:b, b)
        @test f2(30, 3) == (:c, 30) # case: (:c, c)

        xy = (1, 3)
        @test 0 == @when let (a, 1) = xy
            a
        @otherwise
            0
        end

        @test 1 == @when let (a, 3) = xy
            a
        @otherwise
            0
        end

        # multi let bindings
        z = 5
        @test 1 == @when let (a, 3) = xy,
                             5 = z
            a
        @otherwise
            0
        end

        @test 0 == @when let (a, 1) = xy,
                             5 = z
            a
        @otherwise
            0
        end

        @test 0 == @when let (a, 3) = xy,
                             6 = z
            a
        @otherwise
            0
        end
    end

    @testset "@when + @otherwise with many bidings" begin
        function f1(xy, z)
            @when let (a, 1) = xy,
                      5      = z
                a
            @otherwise
                0   # default value
            end
        end
        @test f1((123, 1), 5) == 123    # case: a
        @test f1((123, 3), 5) == 0      # not match `(a, 1) = xy`
        @test f1((123, 1), 1) == 0      # not match `5 = z`

        function f2(ab, c, d, e)
            @when let (a, 1) = ab,
                      5      = c
                a, c
            @when begin :cpp = d; 2.0 = e end
                d, e
            @otherwise
                0
            end
        end
        @test f2((9, 1), 5, :c, 1.0) == (9, 5)          # case: a, c
        @test f2((9, 1), 5, :cpp, 2.0) == (9, 5)        # case: a, c
        @test f2((9, 2), 5, :cpp, 2.0) == (:cpp, 2.0)   # case: d, e

        @test f2((9, 0), 5, :c00, 2.0) == 0  # default case
        @test f2((9, 1), 0, :c00, 2.0) == 0  # default case
        @test f2((9, 0), 5, :cpp, 0.0) == 0  # default case
        @test f2((9, 1), 0, :cpp, 0.0) == 0  # default case
    end

    @testset "error handles" begin
        # no method matching
        @test_macro_throws MethodError @when

        # macro when(assignment, ret)
        #   case: _
        @test_macro_throws SyntaxError @when x 1
        @test_macro_throws SyntaxError("Not match the form of `@when a = b expr`") @when 1 1

        # `gen_when`
        #   case: a
        @test_macro_throws SyntaxError @when 1
        @test_macro_throws SyntaxError @when x
        @test_macro_throws SyntaxError @when @when
        @test_macro_throws SyntaxError @when begin end

        # `@otherwise`
        @test_macro_throws SyntaxError("@otherwise is only used inside @when block, as a token to indicate default case.") @otherwise
    end

end


text:
"""
    sda(x...; beta = 2, eps = 1/100)

Input: list of real distinct numbers.
Output: list of numerators and a common denominator.

Simultaneous diophantine approximation.
I.e. given a list of n distinct real numbers, find rational
approximations using the same denominators.

```julia
julia> sda(sqrt(2), sqrt(3), sqrt(5), sqrt(7))
([22253,27132,35112,41514],15708)
```
"""
function sda(x...; beta=2, eps=1/100)
    β = beta
    ε = eps
    n = length(x)
    A = - eye(n + 1)

    A[1,1] = β^(-n*(n+1)/4) * ε^(n+1)

    for i in 1:n
        A[1,i+1] = diophantine(x[i], ε)
    end

    C, X = LLL(A, 1/4 + 1/β, return_c = true)

    C = Array{Int}(C)

    if sign(C[1,1]) == -1
        return -C[1, 2:end], -C[1, 1]
    else
        return C[1, 2:end], C[1, 1]
    end

end

ext: jl


text:
# # data file for gnash1.mod
# # Original AMPL coding by Sven Leyffer, University of Dundee
#
# # An MPEC from F. Facchinei, H. Jiang and L. Qi, A smoothing method for
# # mathematical programs with equilibrium constraints, Universita di Roma
# # Technical report, 03.96. Problem number 8
#
# param	:	c	K	b	:=
# 	1	10	5	1.2
# 	2	 8	5	1.1
# 	3	 6	5	1.0
# 	4	 4	5	0.9
# 	5	 2	5	0.8	;
#
# param L := 20;
# param g := 1.7;
#
# let x := 75;

c = [10, 8, 6, 4, 2]
K = [5, 5, 5, 5, 5]
b = [1.2, 1.1, 1.0, 0.9, 0.8]
L = 20
g = 1.7
# x = 75

# # gnash1m.mod	QQR2-MN-10-8
# # Original AMPL coding by Sven Leyffer, University of Dundee
#
# # Formulation with mixed complementarity of ...
# #
# # An MPEC from F. Facchinei, H. Jiang and L. Qi, A smoothing method for
# # mathematical programs with equilibrium constraints, Universita di Roma
# # Technical report, 03.96. Problem number 8
# #
# # Arises from Gournot Nash equilibrium , 10 instances are available
# # (see gnash1i.dat, i=0,1,...,9)
#
# # Number of variables:   10
# # Number of constraints:  8
#
# # ... parameters for each firm/company
# param c{1..5};			# c_i
# param K{1..5};			# K_i
# param b{1..5};			# \beta_i
#
# # ... parameters for each problem instance
# param L;			# L
# param g;			# \gamma
#
# # ... computed constants
# param gg := 5000^(1/g);
#
# var x >= 0, <= L;
# var y{1..4};
# var l{1..4};   		        # Multipliers
# var Q = x+y[1]+y[2]+y[3]+y[4];	# defined variable Q
#
# minimize f: c[1]*x + b[1]/(b[1]+1)*K[1]^(-1/b[1])*x^((1+b[1])/b[1])
# 		- x*( gg*Q^(-1/g) );
#
# subject to
#
#    F1: 0 = ( c[2] + K[2]^(-1/b[2])*y[1] ) - ( gg*Q^(-1/g) )
# 				- y[1]*( -1/g*gg*Q^(-1-1/g) ) - l[1];
#    F2: 0 = ( c[3] + K[3]^(-1/b[3])*y[2] ) - ( gg*Q^(-1/g) )
# 				- y[2]*( -1/g*gg*Q^(-1-1/g) ) - l[2];
#    F3: 0 = ( c[4] + K[4]^(-1/b[4])*y[3] ) - ( gg*Q^(-1/g) )
# 				- y[3]*( -1/g*gg*Q^(-1-1/g) ) - l[3];
#    F4: 0 = ( c[5] + K[5]^(-1/b[5])*y[4] ) - ( gg*Q^(-1/g) )
# 				- y[4]*( -1/g*gg*Q^(-1-1/g) ) - l[4];
#
#    g1: 0 <= y[1] <= L  complements   l[1];
#    g3: 0 <= y[2] <= L  complements   l[2];
#    g5: 0 <= y[3] <= L  complements   l[3];
#    g7: 0 <= y[4] <= L  complements   l[4];

using JuMP, Complementarity
using Ipopt

gg = 5000^(1/g)

m = Model(solver=IpoptSolver())

@variable(m, 0 <= x <= L)
@variable(m, y[1:4])
@variable(m, l[1:4])
@variable(m, Q >= 0)
@constraint(m, Q == x+y[1]+y[2]+y[3]+y[4])
@NLobjective(m, Min, c[1]*x + b[1]/(b[1]+1)*K[1]^(-1/b[1])*x^((1+b[1])/b[1])
 		             - x*( gg*Q^(-1/g) ) )

@NLconstraint(m, cnstr[i=1:4], 0 == ( c[i+1] + K[i+1]^(-1/b[i+1])*y[i] ) - ( gg*Q^(-1/g) )
                                  - y[i]*( -1/g*gg*Q^(-1-1/g) ) - l[i] )

for i in 1:4
    @complements(m, l[i], 0 <= y[i] <= L, smooth)
end

solve(m)

@show getobjectivevalue(m)
@assert isapprox(getobjectivevalue(m), -6.11671, atol=1e-4)


text:
# functions for passing out info from simulations, similar to the info return from openai gym
# maintained by @zsunberg

"""
Return a tuple containing the next state and reward and information (usually a `Dict` or `nothing`) from that step.

By default, returns `nothing` as info.
"""
function generate_sri(p::MDP, s, a, rng::AbstractRNG)
    return generate_sr(p, s, a, rng)..., nothing
end

"""
Return a tuple containing the next state, observation, and reward and information (usually a `Dict` or `nothing`) from that step.

By default, returns `nothing` as info.
"""
function generate_sori(p::POMDP, s, a, rng::AbstractRNG)
    return generate_sor(p, s, a, rng)..., nothing
end

"""
    a, ai = action_info(policy, x)

Return a tuple containing the action determined by policy 'p' at state or belief 'x' and information (usually a `Dict` or `nothing`) from the calculation of that action.

By default, returns `nothing` as info.
"""
function action_info(p::Policy, x)
    return action(p, x), nothing
end

"""
    policy, si = solve_info(solver, problem)

Return a tuple containing the policy determined by a solver and information (usually a `Dict` or `nothing`) from the calculation of that policy.

By default, returns `nothing` as info.
"""
function solve_info(s::Solver, problem::Union{POMDP,MDP})
    return solve(s, problem), nothing
end

"""
    bp, i = update_info(updater, b, a, o)

Return a tuple containing the new belief and information (usually a `Dict` or `nothing`) from the belief update.

By default, returns `nothing` as info.
"""
function update_info(up::Updater, b, a, o)
    return update(up, b, a, o), nothing
end


text:
include("../utils/format/Heading.jl")

Heading.main("Constants")
Heading.sub("Note: Cannot redefine a built-in constant or function already in use")

# print(pi)
#! Uncomment the line above, pi will be referenced i.e will
#! be "in use". As a result, the below lines will get error!
#! ERROR: LoadError: cannot assign a value to variable MathConstants.pi from module Main

pi = 0
println(pi)
#: 0

pi = 3.14
println(pi)
#: 3.14


text:
##############################################################################
#
# Vec3f.jl
#
# Part of CVortex.jl
# A fixed size vector (needed for C equivalent structure.)
#
# Copyright 2019 HJA Bird
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
##############################################################################

"""
A 3D Float32 vector.
"""
struct Vec3f
    x :: Float32
    y :: Float32
    z :: Float32
end

function Vec3f(x::Real, y::Real, z::Real)
    return Vec3f(Float32(x), Float32(y), Float32(z))
end

function Vec3f(a::Vector{<:Real})
    @assert(length(a)==3)
    return Vec3f(a[1], a[2], a[3])
end

function Vector{Vec3f}(a::Matrix{<:Real})
	@assert(size(a)[2] == 3, "Input matrix is expected to be n rows by 3 "*
		"columns. Actual input matrix size was " * string(size(a)))
	len = size(a)[1]
	v = Vector{Vec3f}(undef, len)
	for i = 1 : len
		v[i] = convert(Vec3f, a[i, :])
	end
	return v
end

function Vector{T}(a::Vec3f) where T<:Real
	return Vector{T}([a.x, a.y, a.z])
end

function Matrix{T}(a::Vector{Vec3f}) where T <: Real
	len = length(a)
	mat = Matrix{T}(undef, len, 3)
	for i = 1 : len
		mat[i, :] = [a[i].x, a[i].y, a[i].z]
	end
	return mat
end


text:
using Distances

@testset "dp" begin
    #DONE
    @testset "dp_means" begin
        inputs = [[5, 0, 0, 1, 1, 5],
                  [5, 1, 0, 0, 1, 5],
                  [5, 0, 1, 0, 1, 5],
                  [0, 4, 6, 2, 0, 0],
                  [0, 4, 6, 1, 1, 0],
                  [0, 4, 6, 1, 0, 1]]
        radius = 3.0
        μs, sizes, indices, centroids = dp_means(inputs, radius)
        @test μs == [[5, 1/3, 1/3, 1/3, 1, 5],
                     [0, 4, 6, 4/3, 1/3, 1/3]]
        @test sizes == [3, 3]
        @test indices == [[1, 2, 3], [4, 5, 6]]
        @test centroids == [1, 4]
    end

    #DONE
    @testset "C2MC_dp_centers" begin
        inputs = [[5, 0, 0, 1, 1, 5],
                  [5, 1, 0, 0, 1, 5],
                  [5, 0, 1, 0, 1, 5],
                  [0, 4, 6, 2, 0, 0],
                  [0, 4, 6, 1, 1, 0],
                  [0, 4, 6, 1, 0, 1]]
        radius = 3.0
        μs, sizes, indices, centroids = C2MC_dp_centers(inputs, radius)
        @test μs == [[5, 1/3, 1/3, 1/3, 1, 5],
                     [0, 4, 6, 4/3, 1/3, 1/3]]
        @test sizes == [3, 3]
        @test indices == [[1, 2, 3], [4, 5, 6]]
        @test centroids == [1, 4]
    end

    @testset "dp_centers" begin
        inputs = [[5, 0, 0, 1, 1, 5],
                  [5, 1, 0, 0, 1, 5],
                  [5, 0, 1, 0, 1, 5],
                  [0, 4, 6, 2, 0, 0],
                  [0, 4, 6, 1, 1, 0],
                  [0, 4, 6, 1, 0, 1]]
        radii = 3.0
        μs, sizes, indices, centroids = dp_centers(inputs, radii)
        @test μs == [[5, 1/3, 1/3, 1/3, 1, 5],
                     [0, 4, 6, 4/3, 1/3, 1/3]]
        @test sizes == [3, 3]
        @test indices == [[1, 2, 3], [4, 5, 6]]
        @test centroids == [1, 4]
    end

    #recursive version of dp_centers
    @testset "dp_centers" begin
        inputs = [[5, 0, 0, 1, 1, 5],
                  [5, 1, 0, 0, 1, 5],
                  [5, 0, 1, 0, 1, 5],
                  [0, 4, 6, 2, 0, 0],
                  [0, 4, 6, 1, 1, 0],
                  [0, 4, 6, 1, 0, 1]]
        radii = [5.0, 3.0]
        μs, sizes, indices, centroids = dp_centers(inputs, radii)
        @test μs == [[5, 1/3, 1/3, 1/3, 1, 5],
                     [0, 4, 6, 4/3, 1/3, 1/3]]
        @test sizes == [3, 3]
        @test indices == [[1, 2, 3], [4, 5, 6]]
        @test centroids == [1, 4]
    end

end


text:
import Base: ==

struct Call end

iscall(v::IVertex) = value(v) isa Call
iscall(v::IVertex, f) = iscall(v) && isconstant(v[1]) && value(v[1]).value == f

toexpr(c::Call, f, a...) = :($f($(a...)))

function normcalls(ex)
  MacroTools.prewalk(ex) do ex
    @capture(ex, f_(xs__)) ? :($(Call())($f, $(xs...))) : ex
  end
end

# Basic julia sugar

function normops(ex)
  MacroTools.prewalk(ex) do ex
    @match ex begin
      x_ .+ y_ => :((+).($x,$y))
      x_ .- y_ => :((-).($x,$y))
      x_ .* y_ => :((*).($x,$y))
      x_ ./ y_ => :((/).($x,$y))
      _ => ex
    end
  end
end

function desugar(ex)
  MacroTools.prewalk(ex) do ex
    @match ex begin
      (xs__,)   => :($(Call())($tuple, $(xs...)))
      xs_[i__]  => :($(Call())($getindex, $xs, $(i...)))
      (xs_[i__] = v_)  => :($(Call())($setindex!, $xs, $v, $(i...)))
      f_.(xs__) => :($(Call())($broadcast, $f, $(xs...)))
      _ => ex
    end
  end
end

toexpr(::Call, ::typeof(tuple), xs...) = :($(xs...),)
toexpr(::Call, ::typeof(getindex), x, i...) = :($x[$(i...)])
toexpr(::Call, ::typeof(setindex!), x, v, i...) = :($x[$(i...)] = $v)
toexpr(::Call, ::typeof(broadcast), f, xs...) = :($f.($(xs...)))

# Type assert

struct TypeAssert end

toexpr(::TypeAssert, x, T) = :($x::$T)

# Constants

struct Constant
  value
end

toexpr(c::Constant) = c.value

isconstant(v::Vertex) = isa(value(v), Constant)

constant(x) = vertex(Constant(x))
constant(v::Vertex) = vertex(v)

vcall(args...) = vertex(Call(), constant.(args)...)

mapconst(f, v) = map(x -> x isa Constant ? Constant(f(x.value)) : x, v)

withconst(f) = v -> isconstant(v) ? constant(f(v.value.value)) : v

# Blocks

struct Do end

toexpr(::Do, a...) = :($(a...);)

# Line Numbers

struct Line
  file::String
  line::Int
end

const noline = Line("", -1)

function Line(ex::Expr)
  @assert ex.head == :line
  Line(String(ex.args[2]), ex.args[1])
end

Line(l::LineNumberNode) = Line(String(l.file), l.line)

function normlines(ex)
  line = noline
  ex′ = :(;)
  for ex in ex.args
    isline(ex) && (line = Line(ex); continue)
    line == noline && (push!(ex′.args, ex); continue)
    @assert @capture(ex, var_ = val_)
    push!(ex′.args, :($var = $line($val)))
  end
  return ex′
end

function applylines(ex)
  ex′ = :(;)
  for ex in ex.args
    @capture(ex, (var_ = val_) | val_)
    val = MacroTools.postwalk(val) do ex
      @capture(ex, l_Frame(x_)) && return x # Ignore frames for now
      @capture(ex, l_Line(x_)) || return ex
      push!(ex′.args, Expr(:line, l.line, Symbol(l.file)))
      @gensym edge
      push!(ex′.args, :($edge = $x))
      return edge
    end
    isexpr(val, Symbol) ? (ex′.args[end].args[1] = val) :
      push!(ex′.args, var == nothing ? val : :($var = $val))
  end
  return ex′
end

struct Frame{T}
  f::T
end

struct SkipFrame end

function striplines(v)
  postwalk(v) do v
    isa(value(v), Line) || isa(value(v), Frame) ? v[1] : v
  end
end

# Static tuples

# TODO: just use `getindex` and `tuple` to represent these?
struct Split
  n::Int
end

# TODO: printing
function normsplits(ex)
  MacroTools.prewalk(ex) do ex
    @capture(ex, (xs__,) = y_) || return ex
    @gensym edge
    :($edge = $y;
      $((:($(xs[i]) = $(Split(i))($edge)) for i = 1:length(xs))...))
  end |> MacroTools.flatten |> block
end

toexpr(s::Split, x) = :($x[$(s.n)])

group(xs...) = vertex(Call(), constant(tuple), xs...)

# Bindings

struct Bind
  name::Symbol
end

# TODO: printing
function insertbinds(ex)
  ls = map(ex.args) do l
    @capture(l, x_ = y_) || return l
    :($x = $(Bind(x))($y))
  end
  :($(ls...);)
end

# Inputs

struct Input end

Base.show(io::IO, ::Input) = print(io, "Input()")

inputnode(is...) = foldl((x, i) -> vertex(Split(i), x), is, init=constant(Input()))

isinput(v::IVertex) = isa(value(v), Split) && isconstant(v[1]) && value(v[1]).value == Input()

function inputidx(v::IVertex)
  i = Int[]
  while value(v) isa Split
    pushfirst!(i, value(v).n)
    v = v[1]
  end
  v == constant(Input()) ? i : nothing
end

function bumpinputs(v::IVertex)
  prewalk(v) do v
    isinput(v) ?
      inputnode(value(v).n + 1) :
      v
  end
end

function spliceinput(v::IVertex, input::IVertex)
  postwalk(v) do v
    inputidx(v) == [] ? input : v
  end
end

function spliceinputs(v::IVertex, inputs::IVertex...)
  g = group(inputs...)
  prewalk(v) do v
    idx = inputidx(v)
    idx == [] ? g :
    idx ≠ nothing && length(idx) == 1 ? stop(get(collect(inputs), idx[1], v)) : v
  end
end

# TODO: move away from this, it's unreliable
function graphinputs(v::IVertex)
  n = 0
  prewalk(v) do v
    isinput(v) && (n = max(n, value(v).n))
    v
  end
  return n
end

# Closures
# TODO: always close over a single tuple, remove need for arg count

import Base: ==

struct Lambda
  args::Int
  body::IVertex{Any}
end

a::Lambda == b::Lambda = a.args == b.args && a.body == b.body
Base.hash(a::Lambda, h::UInt) = hash(Lambda, hash(a.args, hash(a.body, h)))

islambda(v) = v.value isa Lambda

function normclosures(ex)
  MacroTools.prewalk(shortdef(ex)) do ex
    @capture(ex, (args__,) -> body_) || return ex
    @assert all(arg -> isa(arg, Symbol), args)
    :($(Lambda(length(args), constant(nothing)))($body, $(args...)))
  end
end

function tovertex!(v, bs, f::Lambda, body, args...)
  closed = setdiff(collect(filter(x -> inexpr(body, x), keys(bs))), args)
  vars = [closed..., args...]
  v.value = Lambda(f.args, graphm(merge(bs, bindargs(vars)), normblock(body)))
  thread!(v, graphm.(bs, closed)...)
end

function toexpr(f::Lambda, closed...)
  ex = :(;)
  bind(x, s = gensym(:c)) = (push!(ex.args, :($s = $x)); s)
  closed = [x isa Expr ? bind(x) : x for x in closed]
  args = [gensym(:x) for _ in 1:f.args]
  vars = [closed..., args...]
  body = spliceinputs(f.body, constant.(vars)...)
  push!(ex.args, Expr(:->, :($(args...),), unblock(syntax(body))))
  return unblock(ex)
end

function applybody(f, v::IVertex)
  @assert v.value isa Lambda
  vertex(Lambda(v.value.args, f(v.value.body)), v.inputs...)
end

function prewalkλ(f, v::IVertex)
  prewalk(v) do v
    v = f(v)
    islambda(v) ? applybody(v -> prewalkλ(f, v), v) : v
  end
end

# "Open" Closures

const uid = Ref(UInt64(0))

struct OLambda
  args::Int
  id::UInt64
end

OLambda(args) = OLambda(args, uid[] += 1)

struct LooseEnd
  id::UInt64
end

function λopen(l::Lambda, args...)
  l′ = OLambda(l.args)
  body = spliceinputs(l.body, args...,
                      [vertex(Split(i), constant(LooseEnd(l′.id))) for i = 1:l.args]...)
  vertex(l′, body)
end

λopen(v::IVertex) = λopen(value(v), inputs(v)...)

function λclose(l::OLambda, body)
  in = LooseEnd(l.id)
  vars = []
  body = prewalk(body) do v
    (contains_(v, Constant(in)) || isconstant(v)) && return v
    push!(vars, v)
    vertex(Split(l.args+length(vars)), constant(in))
  end
  body = mapconst(x -> x == in ? Input() : x, body)
  # Swap arguments with variables
  body = spliceinputs(body,
                      [inputnode(i+length(vars)) for i = 1:l.args]...,
                      [inputnode(i) for i = 1:length(vars)]...)
  vertex(Lambda(l.args, body), vars...)
end

λclose(v::IVertex) = λclose(value(v), inputs(v)...)


text:
using Test
using DFTK
using LinearAlgebra
using Random

@testset "Pairwise forces" begin
    a = 5.131570667152971
    lattice = a .* [0 1 1; 1 0 1; 1 1 0]
    # perturb positions away from equilibrium to get nonzero force
    atoms     = [ElementCoulomb(:Li), ElementCoulomb(:H)]
    positions = [ones(3)/8+rand(3)/20, -ones(3)/8]
    symbols   = [:Li, :H]
    V(x, p) = 4*p.ε * ((p.σ/x)^12 - (p.σ/x)^6)
    params = Dict((:Li, :H ) => (; ε=1, σ=2),
                  ( :H, :H ) => (; ε=1, σ=2),
                  (:Li, :Li) => (; ε=1, σ=2))
    term = PairwisePotential(V, params)

    # Test that the constructor has ordered the tuples
    @test (:H, :Li) ∈ keys(term.params)

    model = Model(lattice, atoms, positions; terms=[term])
    basis = PlaneWaveBasis(model; Ecut=20, kgrid=(1, 1, 1))
    forces = compute_forces(basis.terms[1], basis, nothing, nothing)

    # Compare forces to finite differences
    ε=1e-8
    disp=[rand(3) / 20, rand(3) / 20]
    E1 = DFTK.energy_pairwise(lattice, symbols, positions,              term.V, term.params)
    E2 = DFTK.energy_pairwise(lattice, symbols, positions .+ ε .* disp, term.V, term.params)
    @test (E2 - E1) / ε ≈ -dot(disp, forces) atol=abs(1e-6E1)
end


text:
using CayleyDickson
using Base.Test: @test, @test_throws

@test begin
    a = CayleyDickson.randomBigFloat()
    isreal(Quaternion(a))
end

@test begin
    a = 1
    !isreal(Quaternion(a, a, a, a))
end

@test begin
    z = random(Quaternion{Int})
    z == +(z)
end

@test begin
    a = CayleyDickson.randomBigFloat()
    real(Quaternion(a)) == a
end

@test begin
    a = 1
    b = 2
    c = 3
    l = unreal(Quaternion(0, a, b, c))
    r = [a, b, c]
    l == r
end

@test begin
    io = IOBuffer()
    show(io, Quaternion(1, 2, 3, 4))
    l = String(take!(io))
    r = "[1: 1, i: 2, j: 3, ij: 4]"
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    b = CayleyDickson.randomBigFloat()
    l = Quaternion(Binion(a, b))
    r = Quaternion(a, b)
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    b = CayleyDickson.randomBigFloat()
    c = CayleyDickson.randomBigInt()
    l = Quaternion(a, b, c)
    r = Quaternion(a, b, c, 0)
    l == r
end

@test begin
    x = random(Quaternion{BigFloat})
    y = random(Quaternion{BigFloat})
    x != y
end

@test begin
    a = CayleyDickson.randomBigInt()
    z = random(Quaternion{BigInt})
    l = a + z
    r = z + a
    l == r
end

@test begin
    a = random(Binion{BigInt})
    z = random(Quaternion{BigInt})
    l = a + z
    r = z + a
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    z = random(Quaternion{BigInt})
    l = a - z
    r = -(z - a)
    l == r
end

@test begin
    a = random(Binion{BigInt})
    z = random(Quaternion{BigInt})
    l = a - z
    r = -(z - a)
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    l = x + y
    r = y + x
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    l = x * y
    r = y * x
    l != r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    l = x - y
    r = -(y - x)
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    z = random(Quaternion{BigInt})
    l = (x + y) + z
    r = x + (y + z)
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    z = random(Quaternion{BigInt})
    l = (x * y) * z
    r = x * (y * z)
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    conj(conj(x)) == x
end

@test begin
    x = random(Quaternion{Rational{BigInt}})
    inv(inv(x)) == x
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    l = conj(x * y)
    r = conj(y) * conj(x)
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    l = conj(x + y)
    r = conj(x) + conj(y)
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    l = conj(x - y)
    r = conj(x) - conj(y)
    l == r
end

@test begin
    x = random(Quaternion{Rational{BigInt}})
    y = random(Quaternion{Rational{BigInt}})
    l = inv(x * y)
    r = inv(y) * inv(x)
    l == r
end

@test begin
    x = random(Quaternion{Rational{BigInt}})
    y = random(Quaternion{Rational{BigInt}})
    l = inv(x / y)
    r = y / x
    l == r
end

@test begin
    x = random(Quaternion{Rational{BigInt}})
    y = random(Quaternion{Rational{BigInt}})
    l = inv(x \ y)
    r = y \ x
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    z = random(Quaternion{BigInt})
    l = x * (y + z)
    r = (x * y) + (x * z)
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    l = a * (x + y)
    r = (a * x) + (a * y)
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    x = random(Quaternion{BigInt})
    l = a * x
    r = x * a
    l == r
end

@test begin
    a = random(Binion{BigInt})
    x = random(Quaternion{BigInt})
    l = a * x
    r = x * a
    l != r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    z = random(Quaternion{BigInt})
    l = (x + y) * z
    r = (x * z) + (y * z)
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    z = random(Quaternion{BigInt})
    l = x * (y - z)
    r = (x * y) - (x * z)
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    z = random(Quaternion{BigInt})
    l = (x - y) * z
    r = (x * z) - (y * z)
    l == r
end

@test begin
    x = random(Quaternion{BigInt})
    quadrance(x) > big(0)
end

@test begin
    x = random(Quaternion{BigInt})
    y = random(Quaternion{BigInt})
    l = quadrance(x * y)
    r = quadrance(x) * quadrance(y)
    l == r
end

@test_throws ErrorException begin
    inv(Quaternion(0, 0.0))
end

@test_throws ErrorException begin
    random(Quaternion{Int}) / 0
end

@test_throws ErrorException begin
    0 \ random(Quaternion{Int})
end

@test begin
    a = CayleyDickson.randomBigRational()
    z = random(Quaternion{Rational{BigInt}})
    l = z / a
    r = a \ z
    l == r
end

@test begin
    a = CayleyDickson.randomBigRational()
    z = random(Quaternion{Rational{BigInt}})
    l = a / z
    r = z \ a
    l == r
end

@test begin
    z = random(Quaternion{BigInt})
    z == z + zero(Quaternion{BigInt})
end

@test begin
    z = random(Quaternion{BigInt})
    z == z * one(Quaternion{BigInt})
end

@test begin
    z = random(Quaternion{BigInt})
    z == z + zero(z)
end

@test begin
    z = random(Quaternion{BigInt})
    z == z * one(z)
end

@test begin
    i = Quaternion(0,1)
    j = Quaternion(0,0,1)
    anti_commutator(i, j) == zero(Quaternion{Int})
end


text:
using LinearAlgebra: diagind, rmul!
using LinearMaps: CompositeMap, check_dim_mul, diagm
using SparseArrays: spdiagm

import Base: ndims, has_offset_axes, copy, iszero, transpose, +, -, *, /, size
import LinearAlgebra: isdiag, mul!
import LinearMaps: LinearMap, MulStyle, FiveArg, _unsafe_mul!

const Tuple2 = Tuple{Int,Int}
const SInd = IdDict{Tuple2,Int}

struct Shift{T<:Number}
    d::SInd
    v::Vector{T}
end

Lag(v::Number=1.0) = Shift(SInd((-1,0)=>1), [v])
Lead(v::Number=1.0) = Shift(SInd((1,0)=>1), [v])

Shift(i::Int, v::Number=1.0) = Shift(SInd((i,0)=>1), [v])

function Shift(kvs::Pair{Tuple2,T}...) where T
    d = SInd()
    v = T[]
    for (k, s) in kvs
        i = get(d, k, 0)
        if i === 0
            push!(v, s)
            d[k] = length(v)
        else
            v[i] += s
        end
    end
    return Shift(d, v)
end

function _zdiag(v::T, n::Int, i::Int, m::Int) where T
    out = fill(v, n-abs(i))
    m > 0 && (out[1:m] .= zero(T))
    return out
end

(S::Shift)(n::Integer) =
    spdiagm(n, n, (k[1]=>_zdiag(S.v[i], n, k...) for (k, i) in S.d if n-abs(i)>0)...)

eltype(::Type{Shift{T}}) where T = T
ndims(::Shift) = 2
has_offset_axes(::Shift) = false
copy(S::Shift) = Shift(copy(S.d), copy(S.v))
convert(::Type{Shift{T}}, S::Shift) where T = Shift(S.d, convert(Vector{T}, S.v))

isdiag(S::Shift) = all(k[1]==0 for k in keys(S.d))
iszero(S::Shift) = iszero(S.v)

function transpose(S::Shift)
    d = SInd()
    for (k, i) in S.d
        d[(-k[1],k[2])] = i
    end
    # Values are not copied
    return Shift(d, S.v)
end

function _addorsub(S1::Shift, S2::Shift, op)
    d = copy(S1.d)
    v = copy(S1.v)
    for (k, i) in S2.d
        ind = get(S1.d, k, 0)
        v2 = S2.v[i]
        if ind === 0
            push!(v, op(v2))
            d[k] = length(v)
        else
            v[ind] = op(v[ind], v2)
        end
    end
    return Shift(d, v)
end

function _addorsub(S::Shift, M::AbstractMatrix, op)
    r, c = size(M)
    r == c || throw(ArgumentError("matrix is not square"))
    out = op(M)
    @inbounds for (k, i) in S.d
        id, m = k
        -r < id < r && m < r - abs(id) || continue
        d = view(out, diagind(out, id))
        d[m+1:end] .+= S.v[i]
    end
    return out
end

function _mulind(i::Int, m::Int, j::Int, n::Int)
    k = i + j
    l = ifelse(isless(i, 0),
            ifelse(isless(0, j),
                max(m, n) + min(-i, j),
                max(m+j, n)),
            ifelse(isless(j, 0),
                ifelse(isless(k, 0),
                    max(m+k, n),
                    max(m, n-k)),
                max(m, n-i)))
    return k, l
end

(+)(S::Shift) = copy(S)
(+)(S1::Shift, S2::Shift) = _addorsub(S1, S2, +)
(+)(S::Shift, M::AbstractMatrix) = _addorsub(S, M, +)
(+)(M::AbstractMatrix, S::Shift) = S + M

(-)(S::Shift) = Shift(copy(S.d), -S.v)
(-)(S1::Shift, S2::Shift) = _addorsub(S1, S2, -)
(-)(S::Shift, M::AbstractMatrix) = _addorsub(S, M, -)
(-)(M::AbstractMatrix, S::Shift) = M + (-S)

(*)(S::Shift, x::Number) = Shift(copy(S.d), S.v*x)
(*)(x::Number, S::Shift) = S * x
(/)(S::Shift, x::Number) = Shift(copy(S.d), S.v/x)

function (*)(S1::Shift, S2::Shift)
    d = SInd()
    v = eltype(S1)[]
    for (im, i1) in S1.d
        for (jn, i2) in S2.d
            kl = _mulind(im[1], im[2], jn[1], jn[2])
            p = S1.v[i1] * S2.v[i2]
            ind = get(d, kl, 0)
            if ind === 0
                push!(v, p)
                d[kl] = length(v)
            else
                v[ind] = p
            end
        end
    end
    return Shift(d, v)
end

@inline function mul!(C::AbstractVecOrMat, S::Shift, B::AbstractVecOrMat, α::Number, β::Number)
    rmul!(C, β)
    # Need to call size twice in case B is a Vector
    r, c = size(B, 1), size(B, 2)
    @inbounds for (k, i) in S.d
        id, m = k
        -r < id < r && m < r - abs(id) || continue
        v = α * S.v[i]
        # Avoid branching
        adj1 = min(id, 0)
        adj2 = max(id, 0)
        for j in 1:c
            for i in m+1-adj1:r-adj2
                C[i,j] += v * B[i+id,j]
            end
        end
    end
    return C
end

(*)(S::Shift, B::AbstractVecOrMat) = mul!(similar(B), S, B, true, false)

@inline function mul!(C::AbstractVecOrMat, A::AbstractVecOrMat, S::Shift, α::Number, β::Number)
    rmul!(C, β)
    # Need to call size twice in case B is a Vector
    r, c = size(A, 1), size(A, 2)
    @inbounds for (k, i) in S.d
        id, m = k
        -c < id < c && m < c - abs(id) || continue
        v = α * S.v[i]
        # Avoid branching
        adj1 = min(id, 0)
        adj2 = max(id, 0)
        for j in m+1-adj1:c-adj2
            for i in 1:r
                C[i,j] += v * A[i+id,j]
            end
        end
    end
    return C
end

(*)(A::AbstractVecOrMat, S::Shift) = mul!(similar(A), A, S, true, false)

function ==(S1::Shift, S2::Shift)
    length(S1.v) == length(S2.v) || return false
    for (k1, i1) in S1.d
        i2 = get(S2.d, k1, 0)
        i2 === 0 && return false
        S1.v[i1] == S2.v[i2] || return false
    end
    return true
end

struct ShiftMap{T} <: LinearMap{T}
    S::Shift{T}
    N::Int
    function ShiftMap(S::Shift{T}, N::Int) where T
        N > 0 || throw(ArgumentError("size of ShiftMap must be positive"))
        return new{T}(S, N)
    end
end

LinearMap(S::Shift, N::Int) = ShiftMap(S, N)

size(S::ShiftMap) = (S.N, S.N)
MulStyle(::ShiftMap) = FiveArg()
==(S1::ShiftMap, S2::ShiftMap) = S1.S == S2.S && S1.N == S2.N

transpose(S::ShiftMap) = ShiftMap(transpose(S.S), S.N)

_unsafe_mul!(C::AbstractVecOrMat, S::ShiftMap, B::AbstractVecOrMat) =
    mul!(C, S.S, B)

_unsafe_mul!(C::AbstractVecOrMat, S::ShiftMap, B::AbstractVecOrMat, α::Number, β::Number) =
    mul!(C, S.S, B, α, β)

(+)(S1::ShiftMap, S2::ShiftMap) =
    S1.N==S2.N ? ShiftMap(S1.S+S2.S, S1.N) : throw(DimensionMismatch())
(-)(S1::ShiftMap, S2::ShiftMap) =
    S1.N==S2.N ? ShiftMap(S1.S-S2.S, S1.N) : throw(DimensionMismatch())
(*)(x::Number, S::ShiftMap) = ShiftMap(x*S.S, S.N)
(*)(S::ShiftMap, x::Number) = x * S

function (*)(S1::ShiftMap, S2::ShiftMap)
    check_dim_mul(S1, S2)
    return ShiftMap(S1.S*S2.S, S1.N)
end

function Base.:(*)(A::CompositeMap, S::ShiftMap)
    Afirst = first(A.maps)
    if Afirst isa UniformScalingMap
        A2 = ShiftMap(Afirst.S*S.S, S.N)
        return CompositeMap{T}(tuple(A2, Base.tail(A.maps)...))
    else
        return CompositeMap{T}(tuple(S, A.maps...))
    end
end

function (*)(S::ShiftMap, A::CompositeMap)
    Alast = last(A.maps)
    if Alast isa ShiftMap
        A2 = ShiftMap(S.S*Alast, S.N)
        return CompositeMap{T}(tuple(Base.front(A.maps)..., A2))
    else
        return CompositeMap{T}(tuple(A.maps..., S))
    end
end

convert(::Type{Matrix{TF}}, S::ShiftMap) where TF =
    diagm(S.N, S.N, (k[1]=>_zdiag(convert(TF, S.S.v[i]), S.N, k...)
        for (k, i) in S.S.d if S.N-abs(i)>0)...)


text:
mutable struct VariableGeneratorOperations{R,G,T,P}

    # Parameters

    fixedcost::Matrix{Float64}       # $/unit/investment period, r x g
    variablecost::Matrix{Float64}    # $/MW/hour, r x g
    recredit::Matrix{Float64}        # r x g
    capacityfactor::Array{Float64,4} # MW, r x g x t x p

    # Variables

    energydispatch::Array{VariableRef,4} # Energy dispatch (MW, r x g x t x p)
    raisereserve::Array{VariableRef,4}   # Raise reserves provisioned
    lowerreserve::Array{VariableRef,4}   # Lower reserves provisioned

    # Expressions

    fixedcosts::Matrix{ExpressionRef} # ($, r x g)
    variablecosts::Array{ExpressionRef,3} # ($, r x g x p)
    operatingcosts::Matrix{ExpressionRef} # Operating costs ($, r x g)

    ucap::Vector{ExpressionRef} # (MW, r)
    totalenergy::Array{ExpressionRef,3} # MW, r x t x p
    recenergy::Array{ExpressionRef,3} # MW, r x t x p
    totalraisereserve::Array{ExpressionRef,3}
    totallowerreserve::Array{ExpressionRef,3}

    # Constraints

    mingeneration::Array{GreaterThanConstraintRef,4} # (r x g x t x p)
    maxgeneration::Array{LessThanConstraintRef,4}
    minlowerreserve::Array{GreaterThanConstraintRef,4}
    minraisereserve::Array{GreaterThanConstraintRef,4}

    function VariableGeneratorOperations{}(
        fixedcost::Matrix{Float64},
        variablecost::Matrix{Float64},
        recredit::Matrix{Float64},
        capacityfactor::Array{Float64,4}
    )

        R, G, T, P = size(capacityfactor)

        @assert size(fixedcost) == (R, G)
        @assert size(variablecost) == (R, G)
        @assert size(recredit) == (R, G)

        new{R,G,T,P}(fixedcost, variablecost, recredit, capacityfactor)

    end

end

function VariableGeneratorOperations{T}(
    variablegens::VariableGenerators{G},
    regionlookup::Dict{String,Int}, periodlookup::Dict{String,Int},
    variablepath::String
) where {G,T}

    R = length(regionlookup)
    P = length(periodlookup)
    variablelookup = Dict(zip(variablegens.name, 1:G))

    fixedcost = zeros(Float64, R, G)
    variablecost = zeros(Float64, R, G)
    recredit = zeros(Float64, R, G)
    capacityfactor = zeros(Float64, R, G, T, P)

    variabledata = DataFrame!(CSV.File(joinpath(variablepath, "parameters.csv"),
                                       types=scenarios_resource_param_types))

    for row in eachrow(variabledata)
        gen_idx = variablelookup[row.class]
        region_idx = regionlookup[row.region]
        fixedcost[region_idx, gen_idx] = row.fixedcost
        variablecost[region_idx, gen_idx] = row.variablecost
        recredit[region_idx, gen_idx] = row.rec
    end

    availabilitypath = joinpath(variablepath, "availability")

    for classfile in readdir(availabilitypath)

        classmatch = match(r"(.*)\.csv", classfile)
        isnothing(classmatch) && continue
        class = classmatch[1]

        gen_idx = variablelookup[class]

        availabilitydata = DataFrame!(CSV.File(
            joinpath(availabilitypath, classfile)))

        availabilitydata = stack(availabilitydata, Not([:period,:timestep]),
              variable_name=:region, value_name=:availability)

        for row in eachrow(availabilitydata)

            r_idx = regionlookup[row.region]
            t = row.timestep
            p_idx = periodlookup[row.period]

            capacityfactor[r_idx,gen_idx,t,p_idx] = row.availability

        end

    end

    return VariableGeneratorOperations(fixedcost, variablecost, recredit, capacityfactor)

end

function setup!(
    ops::VariableGeneratorOperations{R,G,T,P},
    units::VariableGenerators{G},
    m::Model,
    invs::ResourceInvestments{R,G},
    periodweights::Vector{Float64},
    s::AbstractScenario
) where {R,G,T,P}

    invprob = s.investmentproblem
    Rs = invprob.regionnames
    Gs = units.name
    Ts = string.(1:T)
    Ps = invprob.periodnames

    # Variables

    ops.energydispatch = @variable(m, [1:R, 1:G, 1:T, 1:P])
    varnames!(ops.energydispatch, "energydispatch_variable_$(s.name)", Rs, Gs, Ts, Ps)

    ops.raisereserve   = @variable(m, [1:R, 1:G, 1:T, 1:P])
    varnames!(ops.raisereserve, "raisereserve_variable_$(s.name)", Rs, Gs, Ts, Ps)

    ops.lowerreserve   = @variable(m, [1:R, 1:G, 1:T, 1:P])
    varnames!(ops.lowerreserve, "lowerreserve_variable_$(s.name)", Rs, Gs, Ts, Ps)

    # Expressions

    ops.fixedcosts =
        @expression(m, [r in 1:R, g in 1:G],
                    ops.fixedcost[r,g] * invs.dispatching[r,g])

    ops.variablecosts =
        @expression(m, [r in 1:R, g in 1:G, p in 1:P],
                    sum(ops.variablecost[r,g] * ops.energydispatch[r,g,t,p]
                        for t in 1:T))

    ops.operatingcosts =
        @expression(m, [r in 1:R, g in 1:G],
                    ops.fixedcosts[r,g] +
                    sum(ops.variablecosts[r,g,p] * periodweights[p] for p in 1:P))

    ops.ucap =
        @expression(m, [r in 1:R], G > 0 ? sum(
            invs.dispatching[r,g] * units.maxgen[g] * units.capacitycredit[g]
            for g in 1:G) : 0)

    ops.totalenergy =
        @expression(m, [r in 1:R, t in 1:T, p in 1:P],
                    G > 0 ? sum(ops.energydispatch[r,g,t,p] for g in 1:G) : 0)

    ops.recenergy =
        @expression(m, [r in 1:R, t in 1:T, p in 1:P],
                    G > 0 ? sum(ops.recredit[r,g] * ops.energydispatch[r,g,t,p]
                            for g in 1:G) : 0)

    ops.totalraisereserve =
        @expression(m, [r in 1:R, t in 1:T, p in 1:P],
                    G > 0 ? sum(ops.raisereserve[r,g,t,p] for g in 1:G) : 0)

    ops.totallowerreserve =
        @expression(m, [r in 1:R, t in 1:T, p in 1:P],
                    G > 0 ? sum(ops.lowerreserve[r,g,t,p] for g in 1:G) : 0)

    # Constraints

    ops.mingeneration =
        @constraint(m, [r in 1:R, g in 1:G, t in 1:T, p in 1:P],
                    ops.energydispatch[r,g,t,p] - ops.lowerreserve[r,g,t,p] >=
                    0)

    ops.maxgeneration =
        @constraint(m, [r in 1:R, g in 1:G, t in 1:T, p in 1:P],
                    ops.energydispatch[r,g,t,p] + ops.raisereserve[r,g,t,p] <=
                    invs.dispatching[r,g] * ops.capacityfactor[r,g,t,p] * units.maxgen[g])

    ops.minlowerreserve =
        @constraint(m, [r in 1:R, g in 1:G, t in 1:T, p in 1:P],
                    ops.lowerreserve[r,g,t,p] >= 0)

    ops.minraisereserve =
        @constraint(m, [r in 1:R, g in 1:G, t in 1:T, p in 1:P],
                    ops.raisereserve[r,g,t,p] >= 0)

end

welfare(x::VariableGeneratorOperations) = -sum(x.operatingcosts)


text:
function LinearOperator(in,operators,parameters;adj=true)
	if adj
		d = copy(in)
		m = [];
		for j = 1 : 1 : length(operators)
			op = operators[j]
			m = op(d,true;parameters[j]...)
			d = copy(m)
		end
		return m
	else
		m = copy(in)
		d = [];
		for j = length(operators) : -1 : 1
			op = operators[j]
			d = op(m,false;parameters[j]...)
			m = copy(d)
		end
		return d
	end

end


text:
#
# types.jl --
#
# Type definitions for Julia wrapper of X11 library.
#
#------------------------------------------------------------------------------
#
# Copyright (C) 2017, Éric Thiébaut.
#
# This file is part of Xlib.jl which is licensed under the MIT "Expat" License.
#

# Basic types as defined for the client in `X.h` (also in `Xdefs.h`) and
# `Xlib.h`.

const Atom     = Culong
const Mask     = Culong
const Time     = Culong
const VisualID = Culong
const XID      = Culong
const KeyCode  = Cuchar
const _Bool    = Cint    # renamed to avoid conflicts
const XPointer = Ptr{Cchar}
const Status   = Cint

# Resources

const Colormap = XID
const Cursor   = XID
const Drawable = XID
const Font     = XID
const GContext = XID
const KeySym   = XID
const Pixmap   = XID
const Window   = XID

include("../deps/types.jl")

# Other basic types introduced to deal with Julia/C conversion.

const Opaque = Void       # so that only a pointer of this can be retrieved
const Cfunc = Ptr{Void}   # for C-functions
const XPrivate = Opaque
const XrmHashBucketRec = Opaque

# Extensions need a way to hang private data on some structures.

type XExtData
    number::Cint           # number returned by XRegisterExtension
    next::Ptr{XExtData}    # next item on list of data for structure
    free_private::Cfunc    # called to free private storage
    private_data::XPointer # data private to this extension.
end

# This file contains structures used by the extension mechanism.

immutable XExtCodes    # public to extension, cannot be changed
    extension::Cint    # extension number
    major_opcode::Cint # major op-code assigned by server
    first_event::Cint  # first event number for the extension
    first_error::Cint  # first error number for the extension
end

# Data structure for retrieving info about pixmap formats.

type XPixmapFormatValues
    depth::Cint
    bits_per_pixel::Cint
    scanline_pad::Cint
end

# Data structure for setting graphics context.

type XGCValues
    _function::Cint           # logical operation
    plane_mask::Culong        # plane mask
    foreground::Culong        # foreground pixel
    background::Culong        # background pixel
    line_width::Cint          # line width
    line_style::Cint          # LineSolid, LineOnOffDash, LineDoubleDash
    cap_style::Cint           # CapNotLast, CapButt, CapRound, CapProjecting
    join_style::Cint          # JoinMiter, JoinRound, JoinBevel
    fill_style::Cint          # FillSolid, FillTiled, FillStippled, FillOpaeueStippled
    fill_rule::Cint           # EvenOddRule, WindingRule
    arc_mode::Cint            # ArcChord, ArcPieSlice
    tile::Pixmap              # tile pixmap for tiling operations
    stipple::Pixmap           # stipple 1 plane pixmap for stipping
    ts_x_origin::Cint         # offset for tile or stipple operations
    ts_y_origin::Cint
    font::Font                # default text font for text operations
    subwindow_mode::Cint      # ClipByChildren, IncludeInferiors
    graphics_exposures::_Bool # boolean, should exposures be generated
    clip_x_origin::Cint       # origin for clipping
    clip_y_origin::Cint
    clip_mask::Pixmap         # bitmap clipping; other calls for rects
    dash_offset::Cint         # patterned/dashed line information
    dashes::Cchar
end

# Graphics context.  The contents of this structure are implementation
# dependent.  A GC should be treated as opaque by application code.

immutable _XGC
    ext_data::Ptr{XExtData} # hook for extension to hang data
    gid::GContext           # protocol ID for graphics context
    # FIXME: there is more to this structure, but it is private to Xlib
end

const GC = Ptr{_XGC}

# Visual structure; contains information about colormapping possible.

immutable Visual
    ext_data::Ptr{XExtData} # hook for extension to hang data
    visualid::VisualID      # visual id of this visual
    class::Cint             # class of screen (monochrome, etc.)
    red_mask::Culong        # red mask
    green_mask::Culong      # green mask
    blue_mask::Culong       # blue mask
    bits_per_rgb::Cint      # log base 2 of distinct color values
    map_entries::Cint       # color map entries
end

# Depth structure; contains information for each possible depth.

immutable Depth
    depth::Cint          # this depth (Z) of the depth
    nvisuals::Cint       # number of Visual types at this depth
    visuals::Ptr{Visual} # list of visuals possible at this depth
end

# Information about the screen.  The contents of this structure are
# implementation dependent.  A Screen should be treated as opaque by
# application code.

immutable Screen
    ext_data::Ptr{XExtData}  # hook for extension to hang data
    display::Ptr{Opaque}     # FIXME: back pointer to display structure
    root::Window             # Root window id.
    width::Cint              # width of screen
    height::Cint             # height of screen
    mwidth::Cint             # width of screen in millimeters
    mheight::Cint            # height of screen in millimeters
    ndepths::Cint            # number of depths possible
    depths::Ptr{Depth}       # list of allowable depths on the screen
    root_depth::Cint         # bits per pixel
    root_visual::Ptr{Visual} # root visual
    default_gc::GC           # GC for the root root visual
    cmap::Colormap           # default color map
    white_pixel::Culong      # White pixel value
    black_pixel::Culong      # Black pixel value
    max_maps::Cint           # max color maps
    min_maps::Cint           # min color maps
    backing_store::Cint      # Never, WhenMapped, Always
    save_unders::_Bool
    root_input_mask::Clong   # initial root input mask
end

# Format structure; describes ZFormat data the screen will understand.

immutable ScreenFormat
    ext_data::Ptr{XExtData} # hook for extension to hang data
    depth::Cint             # depth of this image format
    bits_per_pixel::Cint    # bits/pixel at this depth
    scanline_pad::Cint      # scanline must padded to this multiple
end

# Data structure for setting window attributes.

type XSetWindowAttributes
    background_pixmap::Pixmap     # background or None or ParentRelative
    background_pixel::Culong      # background pixel
    border_pixmap::Pixmap         # border of the window
    border_pixel::Culong          # border pixel value
    bit_gravity::Cint             # one of bit gravity values
    win_gravity::Cint             # one of the window gravity values
    backing_store::Cint           # NotUseful, WhenMapped, Always
    backing_planes::Culong        # planes to be preseved if possible
    backing_pixel::Culong         # value to use in restoring planes
    save_under::_Bool             # should bits under be saved? (popups)
    event_mask::Clong             # set of events that should be saved
    do_not_propagate_mask::Culong # set of events that should not propagate
    override_redirect::_Bool      # boolean value for override-redirect
    colormap::Colormap            # color map to be associated with window
    cursor::Cursor                # cursor to be displayed (or None)
end

type XWindowAttributes
    x::Cint; y::Cint              # location of window
    width::Cint; height::Cint     # width and height of window
    border_width::Cint            # border width of window
    depth::Cint                   # depth of window
    visual::Ptr{Visual}           # the associated visual structure
    root::Window                  # root of screen containing window
    class::Cint                   # InputOutput, InputOnly
    bit_gravity::Cint             # one of bit gravity values
    win_gravity::Cint             # one of the window gravity values
    backing_store::Cint           # NotUseful, WhenMapped, Always
    backing_planes::Culong        # planes to be preserved if possible
    backing_pixel::Culong         # value to be used when restoring planes
    save_under::_Bool             # boolean, should bits under be saved?
    colormap::Colormap            # color map to be associated with window
    map_installed::_Bool          # boolean, is color map currently installed
    map_state::Cint               # IsUnmapped, IsUnviewable, IsViewable
    all_event_masks::Clong        # set of events all people have interest in
    your_event_mask::Clong        # my event mask
    do_not_propagate_mask::Culong # set of events that should not propagate
    override_redirect::_Bool      # boolean value for override-redirect
    screen::Ptr{Screen}           # back pointer to correct screen
end

# Data structure for host setting; getting routines.

type XHostAddress
    family::Cint        # for example FamilyInternet
    length::Cint        # length of address, in bytes
    address::Ptr{Cchar} # pointer to where to find the bytes
end

# Data structure for ServerFamilyInterpreted addresses in host routines

type XServerInterpretedAddress
    typelength::Cint                # length of type string, in bytes
    valuelength::Cint       # length of value string, in bytes
    _type::Ptr{Cchar}           # pointer to where to find the type string
    value::Ptr{Cchar}           # pointer to where to find the address
end

# Data structure for "image" data, used by image manipulation routines.

type XImage
    width::Cint            # height of image
    height::Cint           # width of image
    xoffset::Cint          # number of pixels offset in X direction
    format::Cint           # XYBitmap, XYPixmap, ZPixmap
    data::Ptr{Cchar}       # pointer to image data
    byte_order::Cint       # data byte order, LSBFirst, MSBFirst
    bitmap_unit::Cint      # quant. of scanline 8, 16, 32
    bitmap_bit_order::Cint # LSBFirst, MSBFirst
    bitmap_pad::Cint       # 8, 16, 32 either XY or ZPixmap
    depth::Cint            # depth of image
    bytes_per_line::Cint   # accelarator to next line
    bits_per_pixel::Cint   # bits per pixel (ZPixmap)
    red_mask::Culong       # bits in z arrangment
    green_mask::Culong
    blue_mask::Culong
    obdata::XPointer       # hook for the object routines to hang on

    # Image manipulation routines:
    create_image::Cfunc
    destroy_image::Cfunc
    get_pixel::Cfunc
    put_pixel::Cfunc
    sub_image::Cfunc
    add_pixel::Cfunc
end

# Data structure for XReconfigureWindow

type XWindowChanges
    x::Cint
    y::Cint
    width::Cint
    height::Cint
    border_width::Cint
    sibling::Window
    stack_mode::Cint
end

# Data structure used by color operations

immutable XColor
    pixel::Culong
    red::Cushort
    green::Cushort
    blue::Cushort
    flags::Cuchar  # do_red, do_green, do_blue
    pad::Cchar
    XColor(pixel, red, green, blue, flags) =
        new(pixel, red, green, blue, flags, zero(Cchar))
end

# Data structures for graphics operations.  On most machines, these are
# congruent with the wire protocol structures, so reformatting the data can
# be avoided on these architectures.

immutable XSegment
    x1::Cshort
    y1::Cshort
    x2::Cshort
    y2::Cshort
end

immutable XPoint
    x::Cshort
    y::Cshort
end

immutable XRectangle
    x::Cshort
    y::Cshort
    width::Cushort
    height::Cushort
end

immutable XArc
    x::Cshort
    y::Cshort
    width::Cushort
    height::Cushort
    angle1::Cshort
    angle2::Cshort
end

# Data structure for XChangeKeyboardControl

type XKeyboardControl
    key_click_percent::Cint
    bell_percent::Cint
    bell_pitch::Cint
    bell_duration::Cint
    led::Cint
    led_mode::Cint
    key::Cint
    auto_repeat_mode::Cint   # On, Off, Default
end

# Data structure for XGetKeyboardControl

type XKeyboardState
    key_click_percent::Cint
    bell_percent::Cint
    bell_pitch::Cuint
    bell_duration::Cuint
    led_mask::Culong
    global_auto_repeat::Cint
    auto_repeats::Cchar # FIXME: [32] of this;
end

# Data structure for XGetMotionEvents.

immutable XTimeCoord
    time::Time
    x::Cshort
    y::Cshort
end

# Data structure for X{Set,Get} ModifierMapping

type XModifierKeymap
    max_keypermod::Cint       # The server's max # of keys per modifier
    modifiermap::Ptr{KeyCode} # An 8 by max_keypermod array of modifiers
end

# Display datatype maintaining display specific data.  The contents of this
# structure are implementation dependent.  A Display should be treated as
# opaque by application code.

immutable XDisplay
    ext_data::Ptr{XExtData}   # hook for extension to hang data
    private1::Ptr{XPrivate}
    fd::Cint                  # Network socket.
    private2::Cint
    proto_major_version::Cint # major version of server's X protocol
    proto_minor_version::Cint # minor version of servers X protocol
    vendor::Ptr{Cchar}        # vendor of the server hardware
    private3::XID
    private4::XID
    private5::XID
    private6::Cint
    resource_alloc::Ptr{Void}  # allocator function
    byte_order::Cint           # screen byte order, LSBFirst, MSBFirst
    bitmap_unit::Cint          # padding and data requirements
    bitmap_pad::Cint           # padding requirements on bitmaps
    bitmap_bit_order::Cint     # LeastSignificant or MostSignificant
    nformats::Cint             # number of pixmap formats in list
    pixmap_format::Ptr{ScreenFormat}  # pixmap format list
    private8::Cint
    release::Cint              # release of the server
    private9::Ptr{XPrivate}
    private10::Ptr{XPrivate}
    qlen::Cint                 # Length of input event queue
    last_request_read::Culong  # seq number of last event read
    request::Culong            # sequence number of last request.
    private11::XPointer
    private12::XPointer
    private13::XPointer
    private14::XPointer
    max_request_size::Cuint    # maximum number 32 bit words in request
    db::Ptr{XrmHashBucketRec}
    private15::Ptr{Void}
    display_name::Ptr{Cchar}   # "host:display" string used on this connect
    default_screen::Cint       # default screen for operations
    nscreens::Cint             # number of screens on this server
    screens::Ptr{Screen}       # pointer to list of screens
    motion_buffer::Culong      # size of motion buffer
    private16::Culong
    min_keycode::Cint          # minimum defined keycode
    max_keycode::Cint          # maximum defined keycode
    private17::XPointer
    private18::XPointer
    private19::Cint
    xdefaults::Ptr{Cchar}      # contents of defaults from server
    # FIXME: there is more to this structure, but it is private to Xlib
end

#
# Definitions of specific events.
#

type XKeyEvent <: AbstractXEvent
    _type::Cint           # of event
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window        # "event" window it is reported relative to
    root::Window          # root window that the event occurred on
    subwindow::Window     # child window
    time::Time            # milliseconds
    x::Cint
    y::Cint               # pointer x, y coordinates in event window
    x_root::Cint
    y_root::Cint          # coordinates relative to root
    state::Cuint          # key or button mask
    keycode::Cuint        # detail
    same_screen::_Bool    # same screen flag
end
const XKeyPressedEvent  = XKeyEvent
const XKeyReleasedEvent = XKeyEvent

type XButtonEvent <: AbstractXEvent
    _type::Cint           # of event
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window        # "event" window it is reported relative to
    root::Window          # root window that the event occurred on
    subwindow::Window     # child window
    time::Time            # milliseconds
    x::Cint
    y::Cint               # pointer x, y coordinates in event window
    x_root::Cint
    y_root::Cint          # coordinates relative to root
    state::Cuint          # key or button mask
    button::Cuint         # detail
    same_screen::_Bool    # same screen flag
end
const XButtonPressedEvent  = XButtonEvent
const XButtonReleasedEvent = XButtonEvent

type XMotionEvent <: AbstractXEvent
    _type::Cint           # of event
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window        # "event" window reported relative to
    root::Window          # root window that the event occurred on
    subwindow::Window     # child window
    time::Time            # milliseconds
    x::Cint
    y::Cint               # pointer x, y coordinates in event window
    x_root::Cint
    y_root::Cint          # coordinates relative to root
    state::Cuint          # key or button mask
    is_hint::Cchar        # detail
    same_screen::_Bool    # same screen flag
end
const XPointerMovedEvent = XMotionEvent

type XCrossingEvent <: AbstractXEvent
    _type::Cint           # of event
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window        # "event" window reported relative to
    root::Window          # root window that the event occurred on
    subwindow::Window     # child window
    time::Time            # milliseconds
    x::Cint
    y::Cint               # pointer x, y coordinates in event window
    x_root::Cint
    y_root::Cint          # coordinates relative to root
    mode::Cint            # NotifyNormal, NotifyGrab, NotifyUngrab
    detail::Cint          # NotifyAncestor, NotifyVirtual, NotifyInferior,
                          # NotifyNonlinear,NotifyNonlinearVirtual
    same_screen::_Bool    # same screen flag
    focus::_Bool          # boolean focus
    state::Cuint          # key or button mask
end
const XEnterWindowEvent = XCrossingEvent
const XLeaveWindowEvent = XCrossingEvent

type XFocusChangeEvent <: AbstractXEvent
    _type::Cint           # FocusIn or FocusOut
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window        # window of event
    mode::Cint            # NotifyNormal, NotifyWhileGrabbed,
                          # NotifyGrab, NotifyUngrab
    detail::Cint          # NotifyAncestor, NotifyVirtual, NotifyInferior,
                          # NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer,
                          # NotifyPointerRoot, NotifyDetailNone
end
const XFocusInEvent  = XFocusChangeEvent
const XFocusOutEvent = XFocusChangeEvent

# generated on EnterWindow and FocusIn  when KeyMapState selected
type XKeymapEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window
    key_vector::Cbuf32char
end

type XExposeEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window
    x::Cint
    y::Cint
    width::Cint
    height::Cint
    count::Cint           # if non-zero, at least this many more
end

type XGraphicsExposeEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    drawable::Drawable
    x::Cint
    y::Cint
    width::Cint
    height::Cint
    count::Cint           # if non-zero, at least this many more
    major_code::Cint      # core is CopyArea or CopyPlane
    minor_code::Cint      # not defined in the core
end

type XNoExposeEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    drawable::Drawable
    major_code::Cint      # core is CopyArea or CopyPlane
    minor_code::Cint      # not defined in the core
end

type XVisibilityEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window
    state::Cint           # Visibility state
end

type XCreateWindowEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    parent::Window        # parent of the window
    window::Window        # window id of window created
    x::Cint
    y::Cint               # window location
    width::Cint
    height::Cint          # size of window
    border_width::Cint    # border width
    override_redirect::_Bool # creation should be overridden
end

type XDestroyWindowEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    event::Window
    window::Window
end

type XUnmapEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    event::Window
    window::Window
    from_configure::_Bool
end

type XMapEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    event::Window
    window::Window
    override_redirect::_Bool # boolean, is override set...
end

type XMapRequestEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    parent::Window
    window::Window
end

type XReparentEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    event::Window
    window::Window
    parent::Window
    x::Cint
    y::Cint
    override_redirect::_Bool
end

type XConfigureEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    event::Window
    window::Window
    x::Cint
    y::Cint
    width::Cint
    height::Cint
    border_width::Cint
    above::Window
    override_redirect::_Bool
end

type XGravityEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    event::Window
    window::Window
    x::Cint
    y::Cint
end

type XResizeRequestEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window
    width::Cint
    height::Cint
end

type XConfigureRequestEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    parent::Window
    window::Window
    x::Cint
    y::Cint
    width::Cint
    height::Cint
    border_width::Cint
    above::Window
    detail::Cint          # Above, Below, TopIf, BottomIf, Opposite
    value_mask::Culong
end

type XCirculateEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    event::Window
    window::Window
    place::Cint           # PlaceOnTop, PlaceOnBottom
end

type XCirculateRequestEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    parent::Window
    window::Window
    place::Cint           # PlaceOnTop, PlaceOnBottom
end

type XPropertyEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window
    atom::Atom
    time::Time
    state::Cint           # NewValue, Deleted
end

type XSelectionClearEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window
    selection::Atom
    time::Time
end

type XSelectionRequestEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    owner::Window
    requestor::Window
    selection::Atom
    target::Atom
    property::Atom
    time::Time
end

type XSelectionEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    requestor::Window
    selection::Atom
    target::Atom
    property::Atom        # ATOM or None
    time::Time
end

type XColormapEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window
    colormap::Colormap    # COLORMAP or None
    _new::_Bool
    state::Cint           # ColormapInstalled, ColormapUninstalled
end

type XClientMessageEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window
    message_type::Atom
    data::Cbuf5long
end

type XMappingEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window        # unused
    request::Cint         # one of MappingModifier, MappingKeyboard,
                          # MappingPointer
    first_keycode::Cint   # first keycode
    count::Cint           # defines range of change w. first_keycode
end

type XErrorEvent <: AbstractXEvent
    _type::Cint
    display::Ptr{Display} # Display the event was read from
    resourceid::XID       # resource id
    serial::Culong        # serial number of failed request
    error_code::Cuchar    # error code of failed request
    request_code::Cuchar  # Major op-code of failed request
    minor_code::Cuchar    # Minor op-code of failed request
end

type XAnyEvent <: AbstractXEvent
    _type::Cint
    serial::Culong        # # of last request processed by server
    send_event::_Bool     # true if this came from a SendEvent request
    display::Ptr{Display} # Display the event was read from
    window::Window        # window on which event was requested in event mask
end

#
# GenericEvent.  This event is the standard event for all newer extensions.
#

type XGenericEvent <: AbstractXEvent
    _type::Cint           # of event. Always GenericEvent
    serial::Culong        # # of last request processed
    send_event::_Bool     # true if from SendEvent request
    display::Ptr{Display} # Display the event was read from
    extension::Cint       # major opcode of extension that caused the event
    evtype::Cint          # actual event type.
end

type XGenericEventCookie
    _type::Cint           # of event. Always GenericEvent
    serial::Culong        # # of last request processed
    send_event::_Bool     # true if from SendEvent request
    display::Ptr{Display} # Display the event was read from
    extension::Cint       # major opcode of extension that caused the event
    evtype::Cint          # actual event type.
    cookie::Cuint
    data::Ptr{Void}
end

#
# Per character font metric information.
#
type XCharStruct
    lbearing::Cshort    # origin to left edge of raster
    rbearing::Cshort    # origin to right edge of raster
    width::Cshort       # advance to next Cchar's origin
    ascent::Cshort      # baseline to top edge of raster
    descent::Cshort     # baseline to bottom edge of raster
    attributes::Cushort # per char flags (not predefined)
end

#
# To allow arbitrary information with fonts, there are additional properties
# returned.
#
type XFontProp
    name::Atom
    card32::Culong
end

type XFontStruct
    ext_data::Ptr{XExtData}    # hook for extension to hang data
    fid::Font                  # Font id for this font
    direction::Cuint           # hint about direction the font is painted
    min_char_or_byte2::Cuint   # first character
    max_char_or_byte2::Cuint   # last character
    min_byte1::Cuint           # first row that exists
    max_byte1::Cuint           # last row that exists
    all_chars_exist::_Bool     # flag if all characters have non-zero size
    default_char::Cuint        # char to print for undefined character
    n_properties::Cint         # how many properties there are
    properties::Ptr{XFontProp} # pointer to array of additional properties
    min_bounds::XCharStruct    # minimum bounds over all existing char
    max_bounds::XCharStruct    # maximum bounds over all existing char
    per_char::Ptr{XCharStruct} # first_char to last_char information
    ascent::Cint               # log. extent above baseline for spacing
    descent::Cint              # log. descent below baseline for spacing
end

#
# PolyText routines take these as arguments.
#
type XTextItem
    chars::Ptr{Cchar} # pointer to string
    nchars::Cint      # number of characters
    delta::Cint       # delta between strings
    font::Font        # font to print it in, None don't change
end

type XChar2b # normal 16 bit characters are two bytes
    byte1::Cuchar
    byte2::Cuchar
end

type XTextItem16
    chars::Ptr{XChar2b} # two byte characters
    nchars::Cint        # number of characters
    delta::Cint         # delta between strings
    font::Font          # font to print it in, None don't change
end

#
# All the members of `XEDataObject` defined as:
#
#     typedef union { Display *display;
#                     GC gc;
#                     Visual *visual;
#                     Screen *screen;
#                     ScreenFormat *pixmap_format;
#                     XFontStruct *font; } XEDataObject;
#
# are pointers so we aassume the following equivalence:
#
type XEDataObject
    ptr::Ptr{Opaque}
end

type XFontSetExtents
    max_ink_extent::XRectangle
    max_logical_extent::XRectangle
end

# typedef struct _XOM *XOM;
# typedef struct _XOC *XOC, *XFontSet;
const XOM = Ptr{Opaque}
const XOC = Ptr{Opaque}
const XFontSet = Ptr{Opaque}

type XmbTextItem
    chars::Ptr{Cchar}
    nchars::Cint
    delta::Cint
    font_set::XFontSet
end

type XwcTextItem
    chars::Ptr{Cwchar_t}
    nchars::Cint
    delta::Cint
    font_set::XFontSet
end

type XOMCharSetList
    charset_count::Cint
    charset_list::Ptr{Ptr{Cchar}}
end

# Equivalences for C-enumeration `XOrientation`:
const XOrientation = Cint
const XOMOrientation_LTR_TTB = XOrientation(0)
const XOMOrientation_RTL_TTB = XOrientation(1)
const XOMOrientation_TTB_LTR = XOrientation(2)
const XOMOrientation_TTB_RTL = XOrientation(3)
const XOMOrientation_Context = XOrientation(4)

type XOMOrientation
    num_orientation::Cint
    orientation::Ptr{XOrientation}  # Input Text description
end

type XOMFontInfo
    num_font::Cint
    font_struct_list::Ptr{Ptr{XFontStruct}}
    font_name_list::Ptr{Ptr{Cchar}}
end

# typedef struct _XIM *XIM;
const XIM = Ptr{Opaque}

# typedef struct _XIC *XIC;
const XIC = Ptr{Opaque}

# typedef void (*XIMProc)(XIM, XPointer, XPointer);
const XIMProc = Cfunc

# typedef Bool (*XICProc)(XIC, XPointer, Pointer);
const XICProc = Cfunc

# typedef void (*XIDProc)(Display*, XPointer, XPointer);
const XIDProc = Cfunc

const XIMStyle = Culong

type XIMStyles
    count_styles::Cushort
    supported_styles::Ptr{XIMStyle}
end

const XVaNestedList = Ptr{Void}

type XIMCallback
    client_data::XPointer
    callback::XIMProc
end

type XICCallback
    client_data::XPointer
    callback::XICProc
end

const XIMFeedback = Culong

type XIMText
    length::Cushort
    feedback::Ptr{XIMFeedback}
    encoding_is_wchar::_Bool
    string::Ptr{Void} # FIXME:
end

const XIMPreeditState = Culong

type XIMPreeditStateNotifyCallbackStruct
    state::XIMPreeditState
end

const XIMResetState = Culong

const XIMStringConversionFeedback = Culong

type XIMStringConversionText
    length::Cushort
    feedback::Ptr{XIMStringConversionFeedback}
    encoding_is_wchar::_Bool
    string::Ptr{Void} # FIXME:
end

const XIMStringConversionPosition = Cushort

const XIMStringConversionType = Cushort

const XIMStringConversionOperation = Cushort

# Equivalences for C-enumeration `XIMCaretDirection`:
const XIMCaretDirection = Cint
const XIMForwardChar      = XIMCaretDirection(0)
const XIMBackwardChar     = XIMCaretDirection(1)
const XIMForwardWord      = XIMCaretDirection(2)
const XIMBackwardWord     = XIMCaretDirection(3)
const XIMCaretUp          = XIMCaretDirection(4)
const XIMCaretDown        = XIMCaretDirection(5)
const XIMNextLine         = XIMCaretDirection(6)
const XIMPreviousLine     = XIMCaretDirection(7)
const XIMLineStart        = XIMCaretDirection(8)
const XIMLineEnd          = XIMCaretDirection(9)
const XIMAbsolutePosition = XIMCaretDirection(10)
const XIMDontChange       = XIMCaretDirection(11)

type XIMStringConversionCallbackStruct
    position::XIMStringConversionPosition
    direction::XIMCaretDirection
    operation::XIMStringConversionOperation
    factor::Cushort
    text::Ptr{XIMStringConversionText}
end

type XIMPreeditDrawCallbackStruct
    caret::Cint          # Cursor offset within pre-edit string
    chg_first::Cint      # Starting change position
    chg_length::Cint     # Length of the change in character count
    text::Ptr{XIMText}
end

# Equivalences for C-enumeration `XIMCaretStyle`:
const XIMCaretStyle = Cint
const XIMIsInvisible = XIMCaretStyle(0) # Disable caret feedback
const XIMIsPrimary   = XIMCaretStyle(1) # UI defined caret feedback
const XIMIsSecondary = XIMCaretStyle(2) # UI defined caret feedback

type XIMPreeditCaretCallbackStruct
    position::Cint               # Caret offset within pre-edit string
    direction::XIMCaretDirection # Caret moves direction
    style::XIMCaretStyle         # Feedback of the caret
end

# Equivalences for C-enumeration `XIMStatusDataType`:
const XIMStatusDataType = Cint
const XIMTextType = XIMStatusDataType(0)
const XIMBitmapType = XIMStatusDataType(1)

type XIMStatusDrawCallbackStruct
    _type::XIMStatusDataType
    data::Union{Ptr{XIMText},Pixmap} # FIXME:
end

type XIMHotKeyTrigger
    keysym::KeySym
    modifier::Cint
    modifier_mask::Cint
end

type XIMHotKeyTriggers
    num_hot_key::Cint
    key::Ptr{XIMHotKeyTrigger}
end

const XIMHotKeyState = Culong

type XIMValuesList
    count_values::Cushort
    supported_values::Ptr{Ptr{Cchar}}
end


text:
@testset "ShowMakie" begin
    @testset "ImageClassificationSingle" begin
        method = ImageClassificationSingle((16, 16), [1, 2])
        FastAI.test_method_show(method, ShowMakie())
    end
    @testset "ImageClassificationMulti" begin
        method = ImageClassificationMulti((16, 16), [1, 2])
        FastAI.test_method_show(method, ShowMakie())
    end
    @testset "ImageSegmentation" begin
        method = ImageSegmentation((16, 16), [1, 2])
        FastAI.test_method_show(method, ShowMakie())
    end
    @testset "ImageKeypointRegression" begin
        method = ImageKeypointRegression((16, 16), 10)
        FastAI.test_method_show(method, ShowMakie())
    end
end


text:
using MD5
using LibArchive_jll
using Pkg.Artifacts

function import_roms(dir)
    md5_target = Dict{String, String}()
    for line in readlines(joinpath(dir, "md5.txt"))[3:end] # remove 2 header lines
        md5, name = split(line, " ")
        md5_target[md5] = name
    end
    md5_target
    md5_source = Dict{String, String}()
    for filename in readdir(joinpath(dir, "ROMS"))
        key = bytes2hex(open(md5, joinpath(dir, "ROMS", filename)))
        if haskey(md5_source, key)
            rm(joinpath(dir, "ROMS", filename)) # duplicate
        else
            md5_source[key] = filename
        end
    end
    for (md5, filename) in md5_source
        if haskey(md5_target, md5)
            if filename != md5_target[md5]
                mv(joinpath(dir, "ROMS", filename),
                   joinpath(dir, "ROMS", md5_target[md5]), force = true)
            end
        else
            rm(joinpath(dir, "ROMS", filename)) # not supported
        end
    end
end

artifact_toml = joinpath(@__DIR__, "..", "Artifacts.toml")
rom_hash = artifact_hash("atari_roms", artifact_toml)
if rom_hash == nothing || !artifact_exists(rom_hash)
    rom_hash = create_artifact() do artifact_dir
        download("https://raw.githubusercontent.com/mgbellemare/Arcade-Learning-Environment/v0.6.1/md5.txt", joinpath(artifact_dir, "md5.txt"))
        download("http://www.atarimania.com/roms/Roms.rar", joinpath(artifact_dir, "Roms.rar"))
        cd(artifact_dir)
        bsdtar() do exe
            run(`$exe -xf $(joinpath(artifact_dir, "Roms.rar"))`)
            run(`$exe -xf $(joinpath(artifact_dir, "ROMS.zip"))`)
        end
        rm(joinpath(artifact_dir, "Roms.rar"))
        rm(joinpath(artifact_dir, "ROMS.zip"))
        rm(joinpath(artifact_dir, "HC ROMS.zip"))
        import_roms(artifact_dir)
    end
    bind_artifact!(artifact_toml, "atari_roms", rom_hash)
end


text:
using Revise
using Plots
using DynamicalSystems
using DifferentialEquations
using Basins
using ChaosTools

ds = Systems.more_chaos_example()
integ=integrator(ds)
xg=range(-10.,10.,length=100)
yg=range(-10.,10.,length=100)
pmap = poincaremap(ds, (3, 0.), Tmax=1e6; idxs = 1:2, rootkw = (xrtol = 1e-8, atol = 1e-8), reltol=1e-9)
@time bsn = Basins.basins_map2D(xg, yg, pmap)
plot(xg,yg,bsn.basin',seriestype=:heatmap)


text:
module BenchBoundaryConditions

using BenchmarkTools
using LatticeBoltzmann

import LatticeBoltzmann: apply!, Direction, North, East, South, West, BounceBack, MovingWall

suite = BenchmarkGroup()

function initialize_benchmark(q = D2Q9(), τ = 1.0, scale = 2)
    benchmark_problem = LatticeBoltzmann.TGV(q, τ, scale)

    LatticeBoltzmann.initialize(
        LatticeBoltzmann.ZeroVelocityInitialCondition(),
        q,
        benchmark_problem,
    )
end

for q in LatticeBoltzmann.Quadratures
    suite[string(q)] = BenchmarkGroup([string(q), "boundary conditions"])

    τ = 1.0
    f = initialize_benchmark(q, τ)
    NX, NY, NF = size(f)
    for direction in [North(), East(), South(), West()]
        suite[string(q)]["bounce back", direction] = @benchmarkable(
            apply!(bc, $q, f_new, f_old),
            setup = (bc = BounceBack($direction, 1:($NX), 1:($NY));
            f_new = copy($f);
            f_old = copy($f))
        )
    end
end

end  # module
BenchBoundaryConditions.suite


text:
module CRCBS

using Parameters
using DataStructures
using LightGraphs, MetaGraphs, GraphUtils
using LinearAlgebra, SparseArrays
using StaticArrays
using JuMP
using TOML
using Reexport

include("core.jl")
include("cost_models.jl")
include("heuristics.jl")
include("problem_definitions.jl")
include("core_utils.jl")

include("solver_utils.jl")
include("cbs_utils.jl")

include("solvers.jl")
include("solvers/a_star.jl")
include("solvers/cbs.jl")
include("solvers/meta_agent_cbs.jl")
include("solvers/pibt.jl")
include("solvers/flow_solvers.jl")

include("environments/graph_env.jl")
include("environments/cbs_env.jl")
include("environments/multi_stage_cbs_env.jl")
include("environments/meta_agent_cbs_env.jl")

include("helpers/profiling.jl")
include("helpers/problem_instances.jl")
include("helpers/benchmark_interface.jl")

@reexport using GraphUtils

end # module


text:
using Test

using MathOptInterface
const MOI = MathOptInterface
const MOIT = MOI.DeprecatedTest
const MOIU = MOI.Utilities
const MOIB = MOI.Bridges

import SDPT3
const OPTIMIZER = SDPT3.Optimizer()
MOI.set(OPTIMIZER, MOI.Silent(), true)

@testset "SolverName" begin
    @test MOI.get(OPTIMIZER, MOI.SolverName()) == "SDPT3"
end

@testset "supports_incremental_interface" begin
    @test MOI.supports_incremental_interface(OPTIMIZER)
end

# UniversalFallback is needed for starting values, even if they are ignored by SDPT3
const CACHE = MOIU.UniversalFallback(MOIU.Model{Float64}())
const CACHED = MOIU.CachingOptimizer(CACHE, OPTIMIZER)
const BRIDGED = MOIB.full_bridge_optimizer(CACHED, Float64)
const CONFIG = MOIT.Config(atol=1e-4, rtol=1e-4)

@testset "Options" begin
    optimizer = SDPT3.Optimizer(printlevel = 1)
    @test MOI.get(optimizer, MOI.RawOptimizerAttribute("printlevel")) == 1

    param = MOI.RawOptimizerAttribute("bad_option")
    err = MOI.UnsupportedAttribute(param)
    @test_throws err SDPT3.Optimizer(bad_option = 1)
end

@testset "Unit" begin
    MOIT.unittest(BRIDGED, CONFIG, [
        # Need MOI v0.9.5
        "solve_result_index",
        # Get `termcode` -1, i.e. "relative gap < infeasibility".
        "solve_blank_obj",
        # Get `termcode` 3, i.e. "norm(X) or norm(Z) diverging".
        "solve_affine_equalto",
        # Fails because there is no constraint.
        "solve_unbounded_model",
        # `TimeLimitSec` not supported.
        "time_limit_sec",
        # `NumberOfThreads` not supported.
        "number_threads",
        # Integer and ZeroOne sets are not supported
        "solve_integer_edge_cases", "solve_objbound_edge_cases",
        "solve_zero_one_with_bounds_1",
        "solve_zero_one_with_bounds_2",
        "solve_zero_one_with_bounds_3"])
end
@testset "Continuous Linear" begin
    # See explanation in `MOI/test/Bridges/lazy_bridge_OPTIMIZER.jl`.
    # This is to avoid `Variable.VectorizeBridge` which does not support
    # `ConstraintSet` modification.
    MOIB.remove_bridge(BRIDGED, MOIB.Constraint.ScalarSlackBridge{Float64})
    MOIT.contlineartest(BRIDGED, CONFIG, String[
        # Throws error: total dimension of C should be > length(b)
        "linear15",
        "partial_start"
    ])
end
@testset "Continuous Quadratic" begin
    MOIT.contquadratictest(BRIDGED, CONFIG, [
        # Non-convex
        "ncqcp",
        # Quadratic function not strictly convex
        "socp"])
end
@testset "Continuous Conic" begin
    MOIT.contconictest(BRIDGED, CONFIG, [
        # `MOI.OTHER_ERROR`
        "lin2f", "geomean3v",
        # `MOI.NUMERICAL_ERROR`
        "lin4",
        # `ExponentialCone` and `PowerCone` not supported.
        "exp", "dualexp", "pow", "dualpow", "logdet", "relentr",
        # `RootDetConeSquare` -> `RootDetConeTriangle` bridge missing.
        "rootdets"
    ])
end


text:
using TravellingSalesmanProblem
using Test

@testset "TravellingSalesmanProblem.jl" begin
    # Write your own tests here.
end


text:
@extend struct ResultsV2013 <: Results
    Eind::Array{Float64,1} # Industrial emissions (GtCO2 per year)
    Σ::Array{Float64,1} #World Emissions Intensity
    Ω::Array{Float64,1} # Damages as fraction of gross output
    Λ::Array{Float64,1} # Cost of emissions reductions  (trillions USD per year)
    co2price::Array{Float64,1} # Carbon Dioxide Price (per t CO2)
    cprice::Array{Float64,1} # Carbon Price (per t CO2)
    μ_participants::Array{Float64,1} # Emissions Control Rate (participants)
    MCABATE::Array{Float64,1} # Marginal cost of abatement (2005$ per ton CO2)
    co2price_avg::Array{Float64,1} # Carbon Price (Global Average)
    CEMUTOTPER::Array{Float64,1} # Period utility
end

function model_results(model::JuMP.Model, config::Options, params::Parameters, vars::Variables, eqs::Equations)
    years = 2005+(config.tstep*(1:config.N));
    Mₐₜ = getvalue(vars.Mₐₜ);
    Mₐₜppm = getvalue(vars.Mₐₜ)/2.13;
    Mᵤₚ = getvalue(vars.Mᵤₚ);
    Mₗₒ = getvalue(vars.Mₗₒ);
    CCA = getvalue(vars.CCA);
    CCAratio = getvalue(vars.CCA)/config.fosslim;
    Tₐₜ = getvalue(vars.Tₐₜ);
    FORC = getvalue(vars.FORC);
    Tₗₒ = getvalue(vars.Tₗₒ);
    YGROSS = getvalue(vars.YGROSS);
    Ω = getvalue(vars.Ω);
    DAMAGES = getvalue(vars.DAMAGES);
    YNET = getvalue(vars.YNET);
    Λ = getvalue(vars.Λ);
    MCABATE = getvalue(vars.MCABATE);
    Y = getvalue(vars.Y);
    E = getvalue(vars.E);
    Eind = getvalue(vars.Eind);
    Σ = Eind./YGROSS;
    I = getvalue(vars.I);
    K = getvalue(vars.K);
    MPK = config.γₑ.*YGROSS./K;
    C = getvalue(vars.C);
    CPC = getvalue(vars.CPC);
    PERIODU = getvalue(vars.PERIODU);
    UTILITY = getvalue(vars.UTILITY);
    S = getvalue(vars.S);
    co2price = getvalue(vars.CPRICE);
    cprice = getvalue(vars.CPRICE)*3.666;
    μ = getvalue(vars.μ);
    μ_participants = (co2price./params.pbacktime).^(1/(config.θ₂-1));
    co2price_avg = if typeof(params) <: VanillaParameters
        co2price.*params.partfract
    else
        co2price.*getvalue(params.partfract)
    end;
    RI = getvalue(vars.RI);
    CEMUTOTPER = getvalue(vars.CEMUTOTPER);
    scc = if typeof(eqs) <: VanillaEquations
        -1000.*getdual(eqs.eeq)./getdual(eqs.cc)
    else
        -1000.*getdual(eqs.eeq)./getdual(eqs.yy)
    end;
    ResultsV2013(years,Mₐₜ,Mₐₜppm,Mᵤₚ,Mₗₒ,CCA,CCAratio,Tₐₜ,FORC,Tₗₒ,YGROSS,DAMAGES,YNET,
               Y,E,I,K,MPK,C,CPC,PERIODU,UTILITY,S,μ,RI,scc,Eind,Σ,Ω,Λ,co2price,cprice,μ_participants,MCABATE,co2price_avg,CEMUTOTPER)
end


text:
# # Complex Examples
#md # [![](https://mybinder.org/badge_logo.svg)](@__BINDER_ROOT_URL__/notebooks/complexexamples.ipynb)
#md # [![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](@__NBVIEWER_ROOT_URL__/notebooks/complexexamples.ipynb)

# To begin using JuliaPackageDemo.jl we first need to load in the package with the `using` syntax. We will also load in DelimitedFiles.jl so we can import some data.

using JuliaPackageDemo
using DelimitedFiles

# Let's load in some data.
inputdataraw = readdlm("assets/data.csv", ',')
inputdata = vcat(inputdataraw...)

# Now we can use it as the input arguments for [`coolfunction1`](@ref).
## get function values at time points
data = coolfunction1.(inputdata)

# For more information on [`coolfunction1`](@ref) please see the [API](@ref) section. Now we can try something similar with [`coolfunction2`](@ref):

## get function values at time points
data = coolfunction2.(inputdata)

# Finally, let's write that data generated by [`coolfunction2`](@ref) to a file.
open("assets/outputdata.csv", "w") do io
    writedlm(io, data)
end

# For more simple examples, see [Simple Examples](@ref) section.

max_stars_repo_name: moustachio-belvedere/JuliaPackageDemo

max_issues_repo_name: moustachio-belvedere/JuliaPackageDemo

max_forks_repo_name: moustachio-belvedere/JuliaPackageDemo


text:
function read_output(file_path::String)
	file_stream::IOStream = open(file_path, "r")
	file_string::String = readstring(file_stream)
	close(file_stream)

	model::String = read_key(file_string, "model", String)
	number_of_components::Int64 = read_key(file_string, "number_of_components", Int64)
	number_of_abc_samples::Int64 = read_key(file_string, "number_of_abc_samples", Int64)
	m::Array{Float64, 2} = reshape(read_key(file_string, "m", Array{Float64, 1}), (number_of_components, number_of_abc_samples))
	c::Array{Float64, 2} = reshape(read_key(file_string, "c", Array{Float64, 1}), (number_of_components, number_of_abc_samples))
	az::Array{Float64, 2} = reshape(read_key(file_string, "az", Array{Float64, 1}), (number_of_components, number_of_abc_samples))
	dist::Array{Float64, 1} = read_key(file_string, "dist", Array{Float64, 1})
	w::Array{Float64, 1} = read_key(file_string, "w", Array{Float64, 1})
	weighting_scheme::String = read_key(file_string, "weighting_scheme", String)
	gamma::Float64 = read_key(file_string, "gamma", Float64)
	t_exec::Float64 = read_key(file_string, "t_exec", Float64)
	number_of_iterations::Int64 = read_key(file_string, "number_of_iterations", Int64)
	number_of_simulations::Int64 = read_key(file_string, "number_of_simulations", Int64)

	return (
		model,
		number_of_components,
		number_of_abc_samples,
		m,
		c,
		az,
		dist,
		w,
		weighting_scheme,
		gamma,
		t_exec,
		number_of_iterations,
		number_of_simulations)
end


text:
using Counter
using Test

import Counter: Domain, API, Infrastructure
using .Domain, .API, .Infrastructure

@testset "Domain.jl" begin
    item_name = "ar"
    item_nbr = 1000
    item = Item(item_name, item_nbr)
    @test item.name == "ar"
    @test item.nbr == 1000
end

@testset "API.jl" begin
    ar = create("ar", 1000)
    @test ar.name == "ar"
    @test ar.nbr == 1000
end

FILE_COUNTER = "./test_counter.txt"

@testset "Infrastructure.jl" begin
    ar = create("ar", 1000)
    add_to_file(FILE_COUNTER, [ar])
    result = read_from_file(FILE_COUNTER)
    last_item = last(result)
    @test last_item.name == "ar"
    @test last_item.nbr == 1000
    cmd = `rm $FILE_COUNTER`
    run(cmd)
end

@testset "create_new_invoice_nbr" begin
    invoice_nbr = create_new_invoice_nbr(FILE_COUNTER)
    @test invoice_nbr == 1001
    cmd = `rm $FILE_COUNTER`
    run(cmd)
end


text:
using CoupledOscillators
using Test

@testset "CoupledOscillators.jl" begin
    # Write your tests here.
end


text:
# You still can't quite make out the details in the image. Maybe you just
# didn't enhance it enough.
#
# If you enhance the starting input image in the above example a total of 50
# times, 3351 pixels are lit in the final output image.
#
# Start again with the original input image and apply the image enhancement
# algorithm 50 times. How many pixels are lit in the resulting image?

const passes = 50

# read input
iter = eachline("input.txt")
enhancementmap = BitVector(map(isequal('#'), collect(iterate(iter)[1])))
iterate(iter) # blank line
img = BitArray(vcat(map(l -> map(isequal('#'), collect(l))', iter)...))
(width, height) = size(img)

# pad the image with zeros around the edge - we'll pad by 2 in each direction
# because that'll make it easier to grab 9x9 squares, ignoring the edge
(width, height) = (width+4, height+4)
nextimg = falses(width, height)
nextimg[3:(width-2), 3:(height-2)] = img
img = nextimg

# this is used to calculate the numeric value of a 3x3 square of bits
bitvalue = reshape([1 << x for x in 8:-1:0], 3, :)'

# run the image enhancement algo
for _ in 1:passes
  # on each pass the image size increases by one pixel in every direction
  global (width, height) = (width+2, height+2)

  # The edge pixels extend infinitely - on each pass, the 9 pixels that make up
  # the input for the next edge will all have the same value. So, if the
  # current edge is made of falses, the next edge will be the first value from
  # the enhancement map. If the current edge is trues, the next edge will be
  # the last value from the enhancement map.
  edge = img[1,1] ? enhancementmap[end] : enhancementmap[1]
  global nextimg = edge ? trues(width, height) : falses(width, height)

  # enhance image
  for j in 3:(height-2), i in 3:(width-2)
    nextimg[j,i] = enhancementmap[sum(bitvalue .* img[(j-2):j, (i-2):i]) + 1]
  end

  # update img
  global img = nextimg
end

println("Result: ", count(img))