text:
# Faster B-spline basis function

function _s(c::Char, i::Int)
    string(c) * "_" * string(i)
end

function _code_K(p, q)
    join([_s('K', j) for j in 1:p-q+2], ',') *
    " = " *
    join(["(t-" * _s('k', j) * ")÷(" * _s('k', j + q) * "-" * _s('k', j) * ")" for j in 1:p-q+2], ',')
end

function _code_K′(p)
    join([_s('K', j) for j in 1:2], ',') *
    " = " *
    join(["1÷(" * _s('k', j + p) * "-" * _s('k', j) * ")" for j in 1:2], ',')
end

function _code_B(p, q)
    join([_s('B', j) for j in 1:p-q+1], ',') *
    " = " *
    join([_s('K', j) * "*" * _s('B', j) * "+(1-" * _s('K', j + 1) * ")*" * _s('B', j + 1) for j in 1:p-q+1], ',')
end

for p in 0:MAX_DEGREE
    @eval function bsplinebasis₊₀(P::FastBSplineSpace{$p}, i::Integer, t::Real)
        ÷(a, b) = ifelse(b == 0.0, 0.0, a / b)
        $(Meta.parse(join([_s('k', j) for j in 1:p+2], ',') * " = " * join(["P.knots[i+" * string(j) * "]" for j in 0:p+1], ',')))
        $(Meta.parse(
            join([_s('B', j) for j in 1:p+1], ',') * " = " * join(["Float64(" * _s('k', j) * " ≤ t < " * _s('k', j + 1) * ")" for j in 1:p+1], ','),
        ))
        $(Meta.parse("begin " * join([_code_K(p, q) * "\n" * _code_B(p, q) for q in 1:p], '\n') * " end"))
        return B_1
    end
    @eval function bsplinebasis₋₀(P::FastBSplineSpace{$p}, i::Integer, t::Real)
        ÷(a, b) = ifelse(b == 0.0, 0.0, a / b)
        $(Meta.parse(join([_s('k', j) for j in 1:p+2], ',') * " = " * join(["P.knots[i+" * string(j) * "]" for j in 0:p+1], ',')))
        $(Meta.parse(
            join([_s('B', j) for j in 1:p+1], ',') * " = " * join(["Float64(" * _s('k', j) * " < t ≤ " * _s('k', j + 1) * ")" for j in 1:p+1], ','),
        ))
        $(Meta.parse("begin " * join([_code_K(p, q) * "\n" * _code_B(p, q) for q in 1:p], '\n') * " end"))
        return B_1
    end
    @eval function bsplinebasis(P::FastBSplineSpace{$p}, i::Integer, t::Real)
        ÷(a, b) = ifelse(b == 0.0, 0.0, a / b)
        k_end = P.knots[end]
        $(Meta.parse(join([_s('k', j) for j in 1:p+2], ',') * " = " * join(["P.knots[i+" * string(j) * "]" for j in 0:p+1], ',')))
        $(Meta.parse(
            join([_s('B', j) for j in 1:p+1], ',') * " = " * join(["Float64(" * _s('k', j) * " ≤ t < " * _s('k', j + 1) * ")" for j in 1:p+1], ','),
        ))
        $(Meta.parse(_s('B', p + 1) * " += Float64(t == " * _s('k', p + 2) * " == k_end)"))
        $(Meta.parse("begin " * join([_code_K(p, q) * "\n" * _code_B(p, q) for q in 1:p], '\n') * " end"))
        return B_1
    end
end

bsplinebasis′₊₀(P::FastBSplineSpace{0}, i::Integer, t::Real) = 0.0
bsplinebasis′₋₀(P::FastBSplineSpace{0}, i::Integer, t::Real) = 0.0
bsplinebasis′(P::FastBSplineSpace{0}, i::Integer, t::Real) = 0.0

for p in 1:MAX_DEGREE
    @eval function bsplinebasis′₊₀(P::FastBSplineSpace{$p}, i::Integer, t::Real)
        ÷(a, b) = ifelse(b == 0.0, 0.0, a / b)
        $(Meta.parse(join([_s('k', j) for j in 1:p+2], ',') * " = " * join(["P.knots[i+" * string(j) * "]" for j in 0:p+1], ',')))
        $(Meta.parse(
            join([_s('B', j) for j in 1:p+1], ',') * " = " * join(["Float64(" * _s('k', j) * " ≤ t < " * _s('k', j + 1) * ")" for j in 1:p+1], ','),
        ))
        $(Meta.parse("begin " * join([_code_K(p, q) * "\n" * _code_B(p, q) for q in 1:p-1], '\n') * " end"))
        $(Meta.parse(_code_K′(p)))
        B_1 = $p * (K_1 * B_1 - K_2 * B_2)
        return B_1
    end
    @eval function bsplinebasis′₋₀(P::FastBSplineSpace{$p}, i::Integer, t::Real)
        ÷(a, b) = ifelse(b == 0.0, 0.0, a / b)
        $(Meta.parse(join([_s('k', j) for j in 1:p+2], ',') * " = " * join(["P.knots[i+" * string(j) * "]" for j in 0:p+1], ',')))
        $(Meta.parse(
            join([_s('B', j) for j in 1:p+1], ',') * " = " * join(["Float64(" * _s('k', j) * " < t ≤ " * _s('k', j + 1) * ")" for j in 1:p+1], ','),
        ))
        $(Meta.parse("begin " * join([_code_K(p, q) * "\n" * _code_B(p, q) for q in 1:p-1], '\n') * " end"))
        $(Meta.parse(_code_K′(p)))
        B_1 = $p * (K_1 * B_1 - K_2 * B_2)
        return B_1
    end
    # @eval function bsplinebasis′(P::FastBSplineSpace{$p}, i::Integer, t::Real)
    #     ÷(a,b) = ifelse(b == 0.0, 0.0, a/b)
    #     k_end = P.knots[end]
    #     $(Meta.parse(join([_s('k',j) for j in 1:p+2],',')*" = "*join(["P.knots[i+"*string(j)*"]" for j in 0:p+1],',')))
    #     $(Meta.parse(join([_s('B',j) for j in 1:p+1],',')*" = "*join(["Float64("*_s('k',j)*" ≤ t < "*_s('k',j+1)*")" for j in 1:p+1],',')))
    #     $(Meta.parse(_s('B',p+1)*" += Float64(t == "*_s('k',p+2)*" == k_end)"))
    #     $(Meta.parse("begin "*join([_code_K(p,q)*"\n"*_code_B(p,q) for q in 1:p-1],'\n')*" end"))
    #     $(Meta.parse(_code_K′(p)))
    #     B_1 = $p*(K_1*B_1-K_2*B_2)
    #     return B_1
    # end
end

function bsplinebasis′(P::FastBSplineSpace, i::Integer, t::Real)::Float64
    # TODO: faster
    ÷(a, b) = ifelse(b == 0.0, 0.0, a / b)

    p = degree(P)
    k = knots(P)

    B_1, B_2 = bsplinebasis(FastBSplineSpace(p-1, k), i, t), bsplinebasis(FastBSplineSpace(p-1, k), i+1, t)

    K_1, K_2 = 1 ÷ (k[i+p] - k[i]), 1 ÷ (k[i+p+1] - k[i+1])
    B_1 = p * (K_1 * B_1 - K_2 * B_2)

    return B_1
end

# TODO: use @eval macro to produce code
"""
Returns the value of ``B_{(i,0,k)}(t)``.
Assumption:
* ```k_{i} ≤ t < k_{i+1}``
"""
function _bsb0(::Union{Vector{<:Real},Knots}, ::Real, ::Integer)
    return 1.0
end

"""
Returns the values of ``B_{(i,1,k)}(t), B_{(i+1,1,k)}(t)``.
Assumption:
* ``k_{i} ≤ t < k_{i+1}``
"""
function _bsb1(k::Union{Vector{<:Real},Knots}, t::Real, i::Integer)
    B1 = (k[i+1]-t)/(k[i+1]-k[i])
    B2 = (t-k[i])/(k[i+1]-k[i])
    return B1, B2
end

"""
Returns the values of ``B_{(i,2,k)}(t), B_{(i+1,2,k)}(t), B_{(i+2,2,k)}(t)``.
Assumption:
* ``k_{i} ≤ t < k_{i+1}``
"""
@inline function _bsb2(k::Union{Vector{<:Real},Knots}, t::Real, i::Integer)
    B = _bsb1(k, t, i)

    B1 = (k[i+1]-t)/(k[i+1]-k[i-1]) * B[1]
    B2 = (t-k[i-1])/(k[i+1]-k[i-1]) * B[1] +
         (k[i+2]-t)/(k[i+2]-k[i]) * B[2]
    B3 = (t-k[i])/(k[i+2]-k[i]) * B[2]
    return B1, B2, B3
end

"""
Returns the values of ``B_{(i,3,k)}(t), B_{(i+1,3,k)}(t), B_{(i+2,3,k)}(t), B_{(i+3,3,k)}(t)``.
Assumption:
* ``k_{i} ≤ t < k_{i+1}``
"""
@inline function _bsb3(k::Union{Vector{<:Real},Knots}, t::Real, i::Integer)
    B = _bsb2(k, t, i)

    B1 = (k[i+1]-t)/(k[i+1]-k[i-2]) * B[1]
    B2 = (t-k[i-2])/(k[i+1]-k[i-2]) * B[1] +
         (k[i+2]-t)/(k[i+2]-k[i-1]) * B[2]
    B3 = (t-k[i-1])/(k[i+2]-k[i-1]) * B[2] +
         (k[i+3]-t)/(k[i+3]-k[i]) * B[3]
    B4 = (t-k[i])/(k[i+3]-k[i]) * B[3]
    return B1, B2, B3, B4
end

"""
Returns the values of ``B_{(i,4,k)}(t), B_{(i+1,4,k)}(t), B_{(i+2,4,k)}(t), B_{(i+3,4,k)}(t), B_{(i+4,4,k)}(t)``.
Assumption:
* ``k_{i} ≤ t < k_{i+1}``
"""
@inline function _bsb4(k::Union{Vector{<:Real},Knots}, t::Real, i::Integer)
    B = _bsb3(k, t, i)

    B1 = (k[i+1]-t)/(k[i+1]-k[i-3]) * B[1]
    B2 = (t-k[i-3])/(k[i+1]-k[i-3]) * B[1] +
         (k[i+2]-t)/(k[i+2]-k[i-2]) * B[2]
    B3 = (t-k[i-2])/(k[i+2]-k[i-2]) * B[2] +
         (k[i+3]-t)/(k[i+3]-k[i-1]) * B[3]
    B4 = (t-k[i-1])/(k[i+3]-k[i-1]) * B[3] +
         (k[i+4]-t)/(k[i+4]-k[i]) * B[4]
    B5 = (t-k[i])/(k[i+4]-k[i]) * B[4]
    return B1, B2, B3, B4, B5
end

"""
Returns the values of ``B_{(i,5,k)}(t), B_{(i+1,5,k)}(t), B_{(i+2,5,k)}(t), B_{(i+3,5,k)}(t), B_{(i+4,5,k)}(t), B_{(i+5,5,k)}(t)``.
Assumption:
* ``k_{i} ≤ t < k_{i+1}``
"""
@inline function _bsb5(k::Union{Vector{<:Real},Knots}, t::Real, i::Integer)
    B = _bsb4(k, t, i)

    B1 = (k[i+1]-t)/(k[i+1]-k[i-4]) * B[1]
    B2 = (t-k[i-4])/(k[i+1]-k[i-4]) * B[1] +
         (k[i+2]-t)/(k[i+2]-k[i-3]) * B[2]
    B3 = (t-k[i-3])/(k[i+2]-k[i-3]) * B[2] +
         (k[i+3]-t)/(k[i+3]-k[i-2]) * B[3]
    B4 = (t-k[i-2])/(k[i+3]-k[i-2]) * B[3] +
         (k[i+4]-t)/(k[i+4]-k[i-1]) * B[4]
    B5 = (t-k[i-1])/(k[i+4]-k[i-1]) * B[4] +
         (k[i+5]-t)/(k[i+5]-k[i]) * B[5]
    B6 = (t-k[i])/(k[i+5]-k[i]) * B[5]
    return B1, B2, B3, B4, B5, B6
end

@inline function _bsplinebasis(P::FastBSplineSpace{0}, t::Real, i::Integer)
    return _bsb0(P.knots,t,i)
end

@inline function _bsplinebasis(P::FastBSplineSpace{1}, t::Real, i::Integer)
    return _bsb1(P.knots,t,i)
end

@inline function _bsplinebasis(P::FastBSplineSpace{2}, t::Real, i::Integer)
    return _bsb2(P.knots,t,i)
end

@inline function _bsplinebasis(P::FastBSplineSpace{3}, t::Real, i::Integer)
    return _bsb3(P.knots,t,i)
end

@inline function _bsplinebasis(P::FastBSplineSpace{4}, t::Real, i::Integer)
    return _bsb4(P.knots,t,i)
end

@inline function _bsplinebasis(P::FastBSplineSpace{5}, t::Real, i::Integer)
    return _bsb5(P.knots,t,i)
end


text:
inverse_perm(p) = [(1:length(p))[p .== g][1] for g in 1:length(p)]

function permute!(par::Param, p)
    par.xi = par.xi[p,:]
    par.beta = par.beta[p,:]
    par.mu = par.mu[p,:]

    par.bl_shape = par.bl_shape[p]
    par.bl_scale = par.bl_scale[p]
    par.delta = par.delta[p,:]

    par.S = par.S[p,:]
    par.L = par.L[p,:,:]

    par.cind = inverse_perm(p)[par.cind]
    par
end

function permute_vec(par::Param, p)
    vcat(reshape(par.xi[p,:], length(par.xi)),
         reshape(par.beta[p,:], length(par.beta)),
         reshape(par.mu[p,:], length(par.mu)),
         par.bl_shape[p], par.bl_scale[p],
         reshape(par.delta[p,:], length(par.delta)),
         reshape(par.S[p,:], length(par.S)),
         reshape(par.L[p,:,:], length(par.L)),
         inverse_perm(p)[par.cind])
end

function permute!(par::ParamSpline, p)
    par.xi = par.xi[p,:]
    par.beta = par.beta[p,:]
    par.mu = par.mu[p,:]

    par.w = par.w[p,:]
    par.delta = par.delta[p,:]

    par.S = par.S[p,:]
    par.L = par.L[p,:,:]

    par.cind = inverse_perm(p)[par.cind]
    par
end

function permute_vec(par::ParamSpline, p)
    vcat(reshape(par.xi[p,:], length(par.xi)),
         reshape(par.beta[p,:], length(par.beta)),
         reshape(par.mu[p,:], length(par.mu)),
         reshape(par.w[p,:], length(par.w)),
         reshape(par.delta[p,:], length(par.delta)),
         reshape(par.S[p,:], length(par.S)),
         reshape(par.L[p,:,:], length(par.L)),
         inverse_perm(p)[par.cind])
end

relabel!(x::Fit, data::Data) = relabel!(x, MAP(x, data))

function relabel!(x::Tf, map::Tp) where {Tf <: Fit, Tp <: AbstractParam}
    for k in eachindex(x.chains)
        relabel!(x.chains[k], map)
    end
end

## MAP distance relabeling
function relabel!(x::Tc, map::Tp) where {Tc <: Chain, Tp <: AbstractParam}
    M = length(x)
    G = size(map.mu,1)

    switch = 0
    perm = collect(permutations(1:G))
    theta_min = permute_vec(map, perm[1])

    for t in 1:M
        k_min = 1
        d_min = dot(vectorize(permute_vec(x.theta[t], perm[1])), theta_min)

        for k in 1:length(perm)
            d = dot(vectorize(permute_vec(x.theta[t], perm[k])), theta_min)
            if d < d_min
                d_min = d
                k_min = k
            end
        end

        if k_min != 1
            x.theta[t] = permute!(x.theta[t], perm[k_min])
            switch += 1
        end
    end

    @info "Labels switched in $(switch) of $(M) posterior samples!"

    x
end

ext: jl


text:
"""
    abstract Rotation{T} <: StaticMatrix{T}

An abstract type representing 3D rotations. More abstractly, they represent
3×3 unitary (orthogonal) matrices.
"""
abstract Rotation{T} <: StaticMatrix{T}

Base.size{R <: Rotation}(::Union{R,Type{R}}) = (3,3)
Base.ctranspose(r::Rotation) = inv(r)
Base.transpose{T<:Real}(r::Rotation{T}) = inv(r)

# Rotation angles and axes can be obtained by converting to the AngleAxis type
rotation_angle(r::Rotation) = rotation_angle(AngleAxis(r))
rotation_axis(r::Rotation) = rotation_axis(AngleAxis(r))

# Rotation matrices should be orthoginal/unitary. Only the operations we define,
# like multiplication, will stay as Rotations, otherwise users will get an
# SMatrix{3,3} (e.g. rot1 + rot2 -> SMatrix)
Base.@pure StaticArrays.similar_type{R <: Rotation}(::Union{R,Type{R}}) = SMatrix{3, 3, eltype(R), 9}
Base.@pure StaticArrays.similar_type{R <: Rotation, T}(::Union{R,Type{R}}, ::Type{T}) = SMatrix{3, 3, T, 9}

# A random rotation can be obtained easily with unit quaternions
# The unit sphere in R⁴ parameterizes quaternion rotations according to the
# Haar measure of SO(3) - see e.g. http://math.stackexchange.com/questions/184086/uniform-distributions-on-the-space-of-rotations-in-3d
function Base.rand{R <: Rotation}(::Type{R})
    T = eltype(R)
    if T == Any
        T = Float64
    end

    q = Quat(randn(T), randn(T), randn(T), randn(T))
    return R(q)
end

# Useful for converting arrays of rotations to another rotation eltype, for instance.
# Only works because parameters of all the rotations are of a similar form
# Would need to be more sophisticated if we have arbitrary dimensions, etc
@inline function Base.promote_op{R1 <: Rotation, R2 <: Rotation}(::Type{R1}, ::Type{R2})
    if isleaftype(R1)
        return R1
    else
        return R1{eltype(R2)}
    end
end

@inline function Base.:(/)(r1::Rotation, r2::Rotation)
    r1 * inv(r2)
end

@inline function Base.:(\)(r1::Rotation, r2::Rotation)
    inv(r1) * r2
end

################################################################################
################################################################################
"""
    immutable RotMatrix{T} <: Rotation{T}

A statically-sized, 3×3 unitary (orthogonal) matrix.

Note: the orthonormality of the input matrix is *not* checked by the constructor.
"""
immutable RotMatrix{T} <: Rotation{T} # which is <: AbstractMatrix{T}
    mat::SMatrix{3, 3, T, 9} # The final parameter to SMatrix is the "length" of the matrix, 3 × 3 = 9
end

# These 2 functions (plus size) are enough to satisfy the entire StaticArrays interface:
@inline (::Type{RM}){RM<:RotMatrix}(t::NTuple{9}) = RM(SMatrix{3,3}(t))
Base.@propagate_inbounds Base.getindex(r::RotMatrix, i::Integer) = r.mat[i]

# A rotation is more-or-less defined as being an orthogonal (or unitary) matrix
Base.inv(r::RotMatrix) = RotMatrix(r.mat')

# A useful constructor for identity rotation (eye is already provided by StaticArrays, but needs an eltype)
@inline Base.eye(::Type{RotMatrix}) = eye(RotMatrix{Float64})

# By default, composition of rotations will go through RotMatrix, unless overridden
@inline *(r1::Rotation, r2::Rotation) = RotMatrix(r1) * RotMatrix(r2)
@inline *(r1::RotMatrix, r2::Rotation) = r1 * RotMatrix(r2)
@inline *(r1::Rotation, r2::RotMatrix) = RotMatrix(r1) * r2
@inline *(r1::RotMatrix, r2::RotMatrix) = RotMatrix(r1.mat * r2.mat) # TODO check that this doesn't involve extra copying.

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

"""
    isrotation(r)
    isrotation(r, tol)

Check whether `r` is a 3×3 rotation matrix, where `r * r'` is within `tol` of
the identity matrix (using the Frobenius norm). (`tol` defaults to
`1000 * eps(eltype(r))`.)
"""
function isrotation{T}(r::AbstractMatrix{T}, tol::Real = 1000 * eps(eltype(T)))
    if size(r) != (3,3)
        return false
    end

    # Transpose is overloaded for many of our types, so we do it explicitly:
    r_trans = @SMatrix [conj(r[1,1])  conj(r[2,1])  conj(r[3,1]);
                        conj(r[1,2])  conj(r[2,2])  conj(r[2,3]);
                        conj(r[1,3])  conj(r[2,3])  conj(r[3,3])]

    d = vecnorm((r * r_trans) - eye(SMatrix{3,3}))

    return d < tol
end

# A simplification and specialization of the Base.showarray() function makes
# everything sensible at the REPL.
function Base.showarray(io::IO, X::Rotation, repr::Bool = true; header = true)
    if !haskey(io, :compact)
        io = IOContext(io, compact=true)
    end
    if repr
        if isa(X, RotMatrix)
            Base.print_matrix_repr(io, X)
        else
            print(io, typeof(X).name.name)
            n_fields = length(fieldnames(typeof(X)))
            print(io, "(")
            for i = 1:n_fields
                print(io, getfield(X, i))
                if i < n_fields
                    print(io, ", ")
                end
            end
            print(io, ")")
        end
    else
        if header
            print(io, summary(X))
            if !isa(X, RotMatrix)
                n_fields = length(fieldnames(typeof(X)))
                print(io, "(")
                for i = 1:n_fields
                    print(io, getfield(X, i))
                    if i < n_fields
                        print(io, ", ")
                    end
                end
                print(io, ")")
            end
            println(io, ":")
        end
        punct = (" ", "  ", "")
        Base.print_matrix(io, X, punct...)
    end
end

# Removes module name from output, to match other types
function Base.summary(r::Rotation)
    "3×3 $(typeof(r).name.name){$(eltype(r))}"
end


text:
module TestConversions
	using Base.Test
	using DataArrays
	using DataFrames

	df = DataFrame()
	df["A"] = 1:5
	df["B"] = ["A", "B", "C", "D", "E"]
	@assert isa(matrix(df), Matrix{Any})
	@assert isa(matrix(df, Any), Matrix{Any})

	df = DataFrame()
	df["A"] = 1:5
	df["B"] = 1.0:5.0
	@assert isa(matrix(df), Matrix{Real})
	@assert isa(matrix(df, Any), Matrix{Any})
	@assert isa(matrix(df, Float64), Matrix{Float64})

	df = DataFrame()
	df["A"] = 1.0:5.0
	df["B"] = 1.0:5.0
	@assert isa(matrix(df), Matrix{Float64})
	@assert isa(matrix(df, Any), Matrix{Any})
	@assert isa(matrix(df, Int), Matrix{Int})
end


text:
using Test, OMEinsum
using OMEinsum: match_rule, PairWise, Sum, Tr, DefaultRule,
                Permutedims, PTrace, Hadamard, MatMul, nopermute,
                Identity, BatchedContract

@testset "match rule" begin
    ixs = ((1,2), (2,3))
    iy = (1,3)
    @test match_rule(ixs, iy) == MatMul()
    @test match_rule(EinCode(ixs, iy)) == MatMul()

    ixs = ((1,2), (2,3), (3,4))
    iy = (1,4)
    @test match_rule(ixs, iy) == PairWise()

    ixs = ((1,1),)
    iy = ()
    @test match_rule(ixs, iy) == Tr()

    ixs = ((1,1,2),)
    iy = (2,)
    @test match_rule(ixs, iy) == PTrace()

    ixs = ((1,2),)
    iy = (1,)
    @test match_rule(ixs, iy) == Sum()

    ixs = ((1,2,3),)
    iy = (2,1,3)
    @test match_rule(ixs, iy) != Sum()

    ixs = ((1,2),(1,2),(1,2))
    iy = (1,2)
    @test match_rule(ixs, iy) == Hadamard()

    ixs = ((1,2,3),)
    iy = (1,3,2)
    @test match_rule(ixs, iy) == Permutedims()

    ixs = ((1,2),)
    iy = (1,1)
    @test match_rule(ixs, iy) == DefaultRule()

    ix = (1,2,3)
    iy = (1,2)
    @test nopermute(ix,iy)

    ix = (1,2,3)
    iy = (2,1)
    @test !nopermute(ix,iy)

    # 3-argument match_rule
    @test match_rule(Tr, ((1,1),), ())
    @test !match_rule(Tr, ((1,2),), ())
    @test !match_rule(Tr, ((1,1),), (1,))

    @test match_rule(PairWise, ((1,2),(2,3),(3,4),(4,5)), (1,5))
    @test match_rule(PairWise, ((1,2),(2,3),(5,4),(3,4)), (1,5))
    @test !match_rule(PairWise, ((1,2),(2,3),(3,4),(3,5)), (1,5))

    @test match_rule(Sum, ((1,2,3,4),), (1,2))
    @test match_rule(Sum, ((1,2,3,4),), (1,2))
    @test match_rule(Sum, ((1,2,3,4),), (1,2,3,4))
    @test match_rule(Sum, ((1,2,3,4),), (2,1))
    @test !match_rule(Sum, ((1,2,3,4),), (2,1,1))

    @test match_rule(Permutedims, ((1,2),), (2,1))
    @test !match_rule(Permutedims, ((1,2,3),), (2,1))
    @test !match_rule(Permutedims, ((3,3),), (1,3))

    @test match_rule(Hadamard, ((1,2),(1,2)), (1,2))
    @test !match_rule(Hadamard, ((1,2),(2,1)), (1,2))
    @test !match_rule(Hadamard, ((1,2),(1,2)), (1,2,1))

    @test match_rule(PTrace, ((1,1,2),), (2,))
    @test match_rule(PTrace, ((1,1,2,3),), (2,3))
    @test match_rule(PTrace, ((1,1,2,3),), (3,2))
    @test !match_rule(PTrace, ((1,1,2),), (1,2,))

    @test match_rule(MatMul, ((1,2),(2,3)), (1,3))
    @test match_rule(MatMul, ((1,2),(2,3)), (3,1))
    @test match_rule(MatMul, ((2,1),(2,3)), (3,1))
    @test match_rule(MatMul, ((2,1),(3,2)), (3,1))
    @test !match_rule(MatMul, ((1,2,3),(2,3,4)), (1,4))

    @test match_rule(Identity, ((1,2,3),), (1,2,3))
    @test !match_rule(Identity, ((1,2,3),), (1,3,2))

end

@testset "isbatchmul" begin
    @test match_rule(BatchedContract,((1,2), (2,3)), (1,3)) # matmul
    @test match_rule(BatchedContract,((1,2,3), (2,3)), (1,3)) # matvec-batched
    @test match_rule(BatchedContract,((7,1,2,3), (2,4,3,7)), (1,4,3)) # matmat-batched
    @test match_rule(BatchedContract,((3,), (3,)), (3,))  # pure batch
    @test match_rule(BatchedContract,((3,1), (3,)), (3,1))  # batched vector-vector
    @test !match_rule(BatchedContract,((2,2), (2,3)), (1,3))
    @test !match_rule(BatchedContract,((2,1), (2,3)), (1,1))
    @test !match_rule(BatchedContract,((1,2,3), (2,4,3)), (1,3))
end

@testset "match_rule eye candies" begin
    @test match_rule(ein"ij,jk,kl->il") == PairWise()
    @test match_rule(ein"(ij,jk),kl->il") == (OMEinsum.MatMul(), ((OMEinsum.MatMul(), (1, 2)), 3))
end


text:
"""
Struct for MultiVariate (log moneyness x-> S0*exp(x) ) Copula Process

		gaussianCopulaNVariateLogProcess=GaussianCopulaNVariateLogProcess(models::num1,λ::num2,p::num3,λ₊::num4,λ₋::num5) where {num1,num2,num3,num4,num5 <: Number}

Where:\n
		models  =	the processes.
		rho  = 	correlation matrix.
"""
mutable struct GaussianCopulaNVariateLogProcess{num3 <: Number, numtype <: Number} <: NDimensionalMonteCarloProcess{numtype}
    models::Tuple{Vararg{BaseProcess}}
    rho::Matrix{num3}
    function GaussianCopulaNVariateLogProcess(rho::Matrix{num3}, models::BaseProcess...) where {num3 <: Number}
        sz = size(rho)
        @assert sz[1] == sz[2]
        @assert length(models) == sz[1]
        @assert isposdef(rho)
        zero_typed = predict_output_type_zero_(models...) + zero(num3)
        return new{num3, typeof(zero_typed)}(models, rho)
    end
    function GaussianCopulaNVariateLogProcess(models::BaseProcess...)
        len_ = length(models)
        return GaussianCopulaNVariateLogProcess(Matrix{Float64}(I, len_, len_), models...)
    end
    function GaussianCopulaNVariateLogProcess(model1::BaseProcess, model2::BaseProcess, rho::num3) where {num3 <: Number}
        corr_matrix_ = [1.0 rho; rho 1.0]
        @assert isposdef(corr_matrix_)
        return GaussianCopulaNVariateLogProcess(corr_matrix_, model1, model2)
    end
end

support_type(z::GaussianCopulaNVariateLogProcess{num, num1}) where {num <: Number, num1 <: Number} = zero(num)

export GaussianCopulaNVariateLogProcess;

function simulate!(S_Total, mcProcess::GaussianCopulaNVariateLogProcess, rfCurve::AbstractZeroRateCurve, mcBaseData::AbstractMonteCarloConfiguration, T::Number)
    Nsim = mcBaseData.Nsim
    Nstep = mcBaseData.Nstep
    @assert T > 0.0

    ####Simulation
    ## Simulate
    len_ = length(mcProcess.models)
    #S_Total::Array{Matrix{Number}}=[log.(simulate(model_i,rfCurve,mcBaseData,T)./model_i.underlying.S0) for model_i in mcProcess.models];

    for i = 1:len_
        simulate!(S_Total[i], mcProcess.models[i], rfCurve, mcBaseData, T)
    end

    rho = mcProcess.rho
    if (isdiag(rho))
        return
    end
    for i = 1:len_
        S_Total[i] .= log.(S_Total[i] ./ mcProcess.models[i].underlying.S0)
    end
    U_joint = Matrix{eltype(rho)}(undef, len_, Nsim)
    for j = 1:Nstep
        gausscopulagen2!(U_joint, rho, mcBaseData)
        for i = 1:len_
            @views tmp_ = S_Total[i][:, j+1]
            sort!(tmp_)
            @views tmp_ .= (mcProcess.models[i].underlying.S0) .* exp.(Statistics.quantile(tmp_, U_joint[i, :]; sorted = true))
        end
    end

    ## Conclude
    return
end


text:
include("dParse.jl")
include("move.jl")
include("move_user_drop.jl")
include("move_user_move.jl")
include("move_user_resign.jl")
include("server.jl")
include("start.jl")

using BM
using Tk
using move

#change from board to tuples for all ifs
global src = Tuple{Int64,Int64}
global trgt = Tuple{Int64,Int64}
global x,y
global thegrid = Array(Tk.Tk_Button,9,9)

function dispgfx()
  global src
  global trgt
  boardSize=9

  sboard = BM.startGame("standard")
  board = Array(Tuple{String,Char},boardSize,boardSize)
  fill!(board,("_",'_'))
  for (x,y) in keys(sboard.state)
    board[y,x]=(sboard.state[(x,y)][1],sboard.state[(x,y)][2])
  end

#FOR SHOGI

cd("./Images")
bishoppic = ("bishop.gif")
bishopimg = Image(bishoppic)
gold_generalpic = ("gold_general.gif")
gold_generalimg = Image(gold_generalpic)
kingpic = ("king.gif")
kingimg = Image(kingpic)
knightpic = ("knight.gif")
knightimg = Image(knightpic)
lancepic = ("lance.gif")
lanceimg = Image(lancepic)
pawnpic = ("pawn.gif")
pawnimg = Image(pawnpic)
promoted_bishoppic = ("promoted_bishop.gif")
promoted_bishopimg = Image(promoted_bishoppic)
promoted_knightpic = ("promoted_knight.gif")
promoted_knightimg = Image(promoted_knightpic)
promoted_lancepic = ("promoted_lance.gif")
promoted_lanceimg = Image(promoted_lancepic)
promoted_pawnpic = ("promoted_pawn.gif")
promoted_pawnimg = Image(promoted_pawnpic)
promoted_rookpic = ("promoted_rook.gif")
promoted_rookimg = Image(promoted_rookpic)
promoted_silver_generalpic = ("promoted_silver_general.gif")
promoted_silver_generalimg = Image(promoted_silver_generalpic)
rookpic = ("rook.gif")
rookimg = Image(rookpic)
silver_generalpic = ("silver_general.gif")
silver_generalimg = Image(silver_generalpic)
emptypic = ("empty.gif")
emptyimg = Image(emptypic)

bishoprpic = ("bishopr.gif")
bishoprimg = Image(bishoprpic)
gold_generalrpic = ("gold_generalr.gif")
gold_generalrimg = Image(gold_generalrpic)
kingrpic = ("kingr.gif")
kingrimg = Image(kingrpic)
knightrpic = ("knightr.gif")
knightrimg = Image(knightrpic)
lancerpic = ("lancer.gif")
lancerimg = Image(lancerpic)
pawnrpic = ("pawnr.gif")
pawnrimg = Image(pawnrpic)
promoted_bishoprpic = ("promoted_bishopr.gif")
promoted_bishoprimg = Image(promoted_bishoprpic)
promoted_knightrpic = ("promoted_knightr.gif")
promoted_knightrimg = Image(promoted_knightrpic)
promoted_lancerpic = ("promoted_lancer.gif")
promoted_lancerimg = Image(promoted_lancerpic)
promoted_pawnrpic = ("promoted_pawnr.gif")
promoted_pawnrimg = Image(promoted_pawnrpic)
promoted_rookrpic = ("promoted_rookr.gif")
promoted_rookrimg = Image(promoted_rookrpic)
promoted_silver_generalrpic = ("promoted_silver_generalr.gif")
promoted_silver_generalrimg = Image(promoted_silver_generalrpic)
rookrpic = ("rookr.gif")
rookrimg = Image(rookrpic)
silver_generalrpic = ("silver_generalr.gif")
silver_generalrimg = Image(silver_generalrpic)
emptypic = ("empty.gif")
emptyimg = Image(emptypic)

w = Toplevel("Grid")
f = Frame(w, padding = 10); pack(f, expand=true, fill="both")

shogiimgDict = Dict(("_",'_')=>emptyimg,("king",'b')=>kingimg,("bishop",'b')=>bishopimg,("gold general",'b')=>gold_generalimg,
 ("knight",'b')=>knightimg,("lance",'b')=>lanceimg, ("promotedbishop",'b')=>promoted_bishopimg,("promotedlance",'b')=>promoted_lanceimg,("promotedpawn",'b')=>promoted_pawnimg,
 ("promotedrook",'b')=>promoted_rookimg,("promotedsilver",'b')=>promoted_silver_generalimg,("rook",'b')=>rookimg,("silver general",'b')=>silver_generalimg,
 ("pawn",'b')=>pawnimg,("king",'w')=>kingrimg,("bishop",'w')=>bishoprimg,("gold general",'w')=>gold_generalrimg,
  ("knight",'w')=>knightrimg,("lance",'w')=>lancerimg, ("promotedbishop",'w')=>promoted_bishoprimg,
  ("promotedlance",'w')=>promoted_lancerimg,("promotedpawn",'w')=>promoted_pawnrimg,
  ("promotedrook",'w')=>promoted_rookrimg,("promotedsilver",'w')=>promoted_silver_generalrimg,("rook",'w')=>rookrimg,("silver general",'w')=>silver_generalrimg,
  ("pawn",'w')=>pawnrimg)

pimg = Button(f, "",pawnimg)

#=bimg = Button(f, "",bishopimg)
gimg = Button(f, "",gold_generalimg)
nimg = Button(f, "",knightimg)
limg = Button(f, "",lanceimg)
bpimg = Button(f, "",promoted_bishopimg)
npimg = Button(f, "",promoted_knightimg)
lpimg = Button(f, "",promoted_lanceimg)
ppimg = Button(f, "",promoted_pawnimg)
rpimg = Button(f, "",promoted_rookimg)
spimg = Button(f, "",promoted_silver_generalimg)
rimg = Button(f, "",rookimg)
simg = Button(f, "",silver_generalimg)
emptypicimg = Button(f, "", emptyimg)

=#
global x,y
global src,trgt
global thegrid = Array(Tk.Tk_Button,9,9)

for x in 1:9
  for y in 1:9

    thegrid[x,y] = Button(f, "",shogiimgDict[board[x,y]])
    grid(thegrid[x,y],x,y)
    #bind(thegrid[x,y], "command", callbackmove)
    #bind(thegrid[x,y], "<Return>", callbackmove)
    #callback_add(thegrid[x,y], callbackmove)
  end
end

#=
start.startShogi("game.db","S","F","F",0,0,0)

move_user_move.moveUserMove("game1122.db","normal")
destroy(f)
for x in 1:9
  for y in 1:9
    grid(Button(f, "",shogiimgDict[board[x,y]]),x,y)
  end
end
=#

#start playing game
end
#end

#=
start.startShogi("game.db","S","F","F",0,0,0)

move_user_move.moveUserMove("game1122.db","normal")
destroy(f)
for x in 1:9
  for y in 1:9
    grid(Button(f, "",shogiimgDict[board[x,y]]),x,y)
  end
end
=#

#start playing game

#end

#=
if gametype = M
=#

#

function mini()

  boardSize=5
  mboard = BM.startGame("mini")
  board = Array(Tuple{String,Char},boardSize,boardSize)
  fill!(board,("_",'_'))
  for (x,y) in keys(mboard.state)
    board[y,x]=(mboard.state[(x,y)][1],mboard.state[(x,y)][2])
  end

#FOR MINISHOGI

#get rid of imgs in each if
#delete useless piece imgs

cd("./Images")
bishoppic = ("bishop.gif")
bishopimg = Image(bishoppic)
gold_generalpic = ("gold_general.gif")
gold_generalimg = Image(gold_generalpic)
kingpic = ("king.gif")
kingimg = Image(kingpic)
knightpic = ("knight.gif")
knightimg = Image(knightpic)
lancepic = ("lance.gif")
lanceimg = Image(lancepic)
pawnpic = ("pawn.gif")
pawnimg = Image(pawnpic)
promoted_bishoppic = ("promoted_bishop.gif")
promoted_bishopimg = Image(promoted_bishoppic)
promoted_knightpic = ("promoted_knight.gif")
promoted_knightimg = Image(promoted_knightpic)
promoted_lancepic = ("promoted_lance.gif")
promoted_lanceimg = Image(promoted_lancepic)
promoted_pawnpic = ("promoted_pawn.gif")
promoted_pawnimg = Image(promoted_pawnpic)
promoted_rookpic = ("promoted_rook.gif")
promoted_rookimg = Image(promoted_rookpic)
promoted_silver_generalpic = ("promoted_silver_general.gif")
promoted_silver_generalimg = Image(promoted_silver_generalpic)
rookpic = ("rook.gif")
rookimg = Image(rookpic)
silver_generalpic = ("silver_general.gif")
silver_generalimg = Image(silver_generalpic)
emptypic = ("empty.gif")
emptyimg = Image(emptypic)

bishoprpic = ("bishopr.gif")
bishoprimg = Image(bishoprpic)
gold_generalrpic = ("gold_generalr.gif")
gold_generalrimg = Image(gold_generalrpic)
kingrpic = ("kingr.gif")
kingrimg = Image(kingrpic)
knightrpic = ("knightr.gif")
knightrimg = Image(knightrpic)
lancerpic = ("lancer.gif")
lancerimg = Image(lancerpic)
pawnrpic = ("pawnr.gif")
pawnrimg = Image(pawnrpic)
promoted_bishoprpic = ("promoted_bishopr.gif")
promoted_bishoprimg = Image(promoted_bishoprpic)
promoted_knightrpic = ("promoted_knightr.gif")
promoted_knightrimg = Image(promoted_knightrpic)
promoted_lancerpic = ("promoted_lancer.gif")
promoted_lancerimg = Image(promoted_lancerpic)
promoted_pawnrpic = ("promoted_pawnr.gif")
promoted_pawnrimg = Image(promoted_pawnrpic)
promoted_rookrpic = ("promoted_rookr.gif")
promoted_rookrimg = Image(promoted_rookrpic)
promoted_silver_generalrpic = ("promoted_silver_generalr.gif")
promoted_silver_generalrimg = Image(promoted_silver_generalrpic)
rookrpic = ("rookr.gif")
rookrimg = Image(rookrpic)
silver_generalrpic = ("silver_generalr.gif")
silver_generalrimg = Image(silver_generalrpic)
emptypic = ("empty.gif")
emptyimg = Image(emptypic)

w = Toplevel("Grid")
f = Frame(w, padding = 10); pack(f, expand=true, fill="both")

minishogiimgDict = Dict(("_",'_')=>emptyimg,("king",'b')=>kingimg,("bishop",'b')=>bishopimg,("gold general",'b')=>gold_generalimg,
 ("knight",'b')=>knightimg,("lance",'b')=>lanceimg, ("promotedbishop",'b')=>promoted_bishopimg,("promotedlance",'b')=>promoted_lanceimg,("promotedpawn",'b')=>promoted_pawnimg,
 ("promotedrook",'b')=>promoted_rookimg,("promotedsilver",'b')=>promoted_silver_generalimg,("rook",'b')=>rookimg,("silver general",'b')=>silver_generalimg,
 ("pawn",'b')=>pawnimg,("king",'w')=>kingrimg,("bishop",'w')=>bishoprimg,("gold general",'w')=>gold_generalrimg,
  ("knight",'w')=>knightrimg,("lance",'w')=>lancerimg, ("promotedbishop",'w')=>promoted_bishoprimg,
  ("promotedlance",'w')=>promoted_lancerimg,("promotedpawn",'w')=>promoted_pawnrimg,
  ("promotedrook",'w')=>promoted_rookrimg,("promotedsilver",'w')=>promoted_silver_generalrimg,("rook",'w')=>rookrimg,("silver general",'w')=>silver_generalrimg,
  ("pawn",'w')=>pawnrimg)

pimg = Button(f, "",pawnimg)

#=bimg = Button(f, "",bishopimg)
gimg = Button(f, "",gold_generalimg)
nimg = Button(f, "",knightimg)
limg = Button(f, "",lanceimg)
bpimg = Button(f, "",promoted_bishopimg)
npimg = Button(f, "",promoted_knightimg)
lpimg = Button(f, "",promoted_lanceimg)
ppimg = Button(f, "",promoted_pawnimg)
rpimg = Button(f, "",promoted_rookimg)
spimg = Button(f, "",promoted_silver_generalimg)
rimg = Button(f, "",rookimg)
simg = Button(f, "",silver_generalimg)
emptypicimg = Button(f, "", emptyimg)

=#
for x in 1:5
  for y in 1:5
    grid(Button(f, "",minishogiimgDict[board[x,y]]),x,y)
  end
end

#start playing game

end

#=
if gametype = C
=#

function chu()
  boardSize=12
  cboard = BM.startGame("chu")
  board = Array(Tuple{String,Char},boardSize,boardSize)
  fill!(board,("_",'_'))
  for (x,y) in keys(cboard.state)
    board[y,x]=(cboard.state[(x,y)][1],cboard.state[(x,y)][2])
  end

#FOR CHU SHOGI

#get rid of imgs in each if
#add extra piece pics

cd("./Images")
bishoppic = ("bishop.gif")
bishopimg = Image(bishoppic)
gold_generalpic = ("gold_general.gif")
gold_generalimg = Image(gold_generalpic)
kingpic = ("king.gif")
kingimg = Image(kingpic)
knightpic = ("knight.gif")
knightimg = Image(knightpic)
lancepic = ("lance.gif")
lanceimg = Image(lancepic)
pawnpic = ("pawn.gif")
pawnimg = Image(pawnpic)
promoted_bishoppic = ("promoted_bishop.gif")
promoted_bishopimg = Image(promoted_bishoppic)
promoted_knightpic = ("promoted_knight.gif")
promoted_knightimg = Image(promoted_knightpic)
promoted_lancepic = ("promoted_lance.gif")
promoted_lanceimg = Image(promoted_lancepic)
promoted_pawnpic = ("promoted_pawn.gif")
promoted_pawnimg = Image(promoted_pawnpic)
promoted_rookpic = ("promoted_rook.gif")
promoted_rookimg = Image(promoted_rookpic)
promoted_silver_generalpic = ("promoted_silver_general.gif")
promoted_silver_generalimg = Image(promoted_silver_generalpic)
rookpic = ("rook.gif")
rookimg = Image(rookpic)
silver_generalpic = ("silver_general.gif")
silver_generalimg = Image(silver_generalpic)
emptypic = ("empty.gif")
emptyimg = Image(emptypic)

bishoprpic = ("bishopr.gif")
bishoprimg = Image(bishoprpic)
gold_generalrpic = ("gold_generalr.gif")
gold_generalrimg = Image(gold_generalrpic)
kingrpic = ("kingr.gif")
kingrimg = Image(kingrpic)
knightrpic = ("knightr.gif")
knightrimg = Image(knightrpic)
lancerpic = ("lancer.gif")
lancerimg = Image(lancerpic)
pawnrpic = ("pawnr.gif")
pawnrimg = Image(pawnrpic)
promoted_bishoprpic = ("promoted_bishopr.gif")
promoted_bishoprimg = Image(promoted_bishoprpic)
promoted_knightrpic = ("promoted_knightr.gif")
promoted_knightrimg = Image(promoted_knightrpic)
promoted_lancerpic = ("promoted_lancer.gif")
promoted_lancerimg = Image(promoted_lancerpic)
promoted_pawnrpic = ("promoted_pawnr.gif")
promoted_pawnrimg = Image(promoted_pawnrpic)
promoted_rookrpic = ("promoted_rookr.gif")
promoted_rookrimg = Image(promoted_rookrpic)
promoted_silver_generalrpic = ("promoted_silver_generalr.gif")
promoted_silver_generalrimg = Image(promoted_silver_generalrpic)
rookrpic = ("rookr.gif")
rookrimg = Image(rookrpic)
silver_generalrpic = ("silver_generalr.gif")
silver_generalrimg = Image(silver_generalrpic)
emptypic = ("empty.gif")
emptyimg = Image(emptypic)

w = Toplevel("Grid")
f = Frame(w, padding = 10); pack(f, expand=true, fill="both")

 # add to img Dict
imgDict = Dict(('_','_')=>emptyimg,("king",'b')=>kingimg,("bishop",'b')=>bishopimg,("gold general",'b')=>gold_generalimg,
 ("knight",'b')=>knightimg,("lance",'b')=>lanceimg, ("promotedbishop",'b')=>promoted_bishopimg,("promotedlance",'b')=>promoted_lanceimg,("promotedpawn",'b')=>promoted_pawnimg,
 ("promotedrook",'b')=>promoted_rookimg,("promotedsilver",'b')=>promoted_silver_generalimg,("rook",'b')=>rookimg,("silver general",'b')=>silver_generalimg,
 ("pawn",'b')=>pawnimg,("king",'w')=>kingrimg,("bishop",'w')=>bishoprimg,("gold general",'w')=>gold_generalrimg,
  ("knight",'w')=>knightrimg,("lance",'w')=>lancerimg, ("promotedbishop",'w')=>promoted_bishoprimg,
  ("promotedlance",'w')=>promoted_lancerimg,("promotedpawn",'w')=>promoted_pawnrimg,
  ("promotedrook",'w')=>promoted_rookrimg,("promotedsilver",'w')=>promoted_silver_generalrimg,("rook",'w')=>rookrimg,("silver general",'w')=>silver_generalrimg,
  ("pawn",'w')=>pawnrimg)

  #="bishop" => bishop, "gold general" => goldGeneral, "king" => king, "lance" => lance, "knight" => knight,
   "pawn" => pawn, "rook" => rook, "silver general" => silverGeneral,
  "phoenix" => phoenix, "vertical mover" => verticalMover, "go-between" => goBetween,
   "queen" => queen, "lion" => lion, "dragon king" => dragonKing, "dragon horse", dragonHorse, "side mover" => sideMover,
  "kirin" => kirin, "blind tiget"=> blindTiger, "reverse chariot" => reverseChariot,
   "drunk elephant" => drunkElephant, "ferocious leopard" => ferociousLeopard, "blind tiger" => blindTiger=#

   board[(2,1)] = ("ferocious leopard",'w')
   board[(2,12)] = ("ferocious leopard",'b')
   board[(3,1)] = ("copper general",'w')
   board[(3,12)] = ("copper general",'b')
   board[(7,1)] = ("drunk elephant",'w')
   board[(6,12)] = ("drunk elephant",'b')
   board[(1,2)] = ("reverse chariot",'w')
   board[(1,11)] = ("reverse chariot",'b')
   board[(5,2)] = ("blind tiger",'w')
   board[(5,11)] = ("blind tiger",'b')
   board[(6,2)] = ("kirin",'w')
   board[(7,11)] = ("kirin",'b')
   board[(7,2)] = ("phoenix",'w')
   board[(6,11)] = ("phoenix",'b')
   board[(1,3)] = ("side mover",'w')
   board[(1,10)] = ("side mover",'b')
   board[(2,3)] = ("vertical mover",'w')
   board[(2,10)] = ("vertical mover",'b')
   board[(4,3)] = ("dragon horse",'w')
   board[(4,10)] = ("dragon horse",'b')
   board[(5,3)] = ("dragon king",'w')
   board[(5,10)] = ("dragon king",'b')
   board[(6,3)] = ("lion",'w')
   board[(7,10)] = ("lion",'b')
   board[(7,3)] = ("queen",'w')
   board[(6,10)] = ("queen",'b')
   board[(4,5)] = ("go-between",'w')
   board[(4,8)] = ("go-between",'b')

pimg = Button(f, "",pawnimg)

#=bimg = Button(f, "",bishopimg)
gimg = Button(f, "",gold_generalimg)
nimg = Button(f, "",knightimg)
limg = Button(f, "",lanceimg)
bpimg = Button(f, "",promoted_bishopimg)
npimg = Button(f, "",promoted_knightimg)
lpimg = Button(f, "",promoted_lanceimg)
ppimg = Button(f, "",promoted_pawnimg)
rpimg = Button(f, "",promoted_rookimg)
spimg = Button(f, "",promoted_silver_generalimg)
rimg = Button(f, "",rookimg)
simg = Button(f, "",silver_generalimg)
emptypicimg = Button(f, "", emptyimg)

=#
for x in 1:12
  for y in 1:12
    grid(Button(f, "c g"),x,y)
  end
end
#start playing game

end

#=
if gametype = T
=#

function tenjiku()
  boardSize=16
  mboard = BM.startGame("tenjiku")
  board = Array(Tuple{String,Char},boardSize,boardSize)
  fill!(board,("_",'_'))
  for (x,y) in keys(sboard.state)
    board[y,x]=(sboard.state[(x,y)][1],sboard.state[(x,y)][2])
  end

#FOR TENJIKU SHOGI

#get rid of imgs in each if
#add extra piece pics

cd("./Images")
bishoppic = ("bishop.gif")
bishopimg = Image(bishoppic)
gold_generalpic = ("gold_general.gif")
gold_generalimg = Image(gold_generalpic)
kingpic = ("king.gif")
kingimg = Image(kingpic)
knightpic = ("knight.gif")
knightimg = Image(knightpic)
lancepic = ("lance.gif")
lanceimg = Image(lancepic)
pawnpic = ("pawn.gif")
pawnimg = Image(pawnpic)
promoted_bishoppic = ("promoted_bishop.gif")
promoted_bishopimg = Image(promoted_bishoppic)
promoted_knightpic = ("promoted_knight.gif")
promoted_knightimg = Image(promoted_knightpic)
promoted_lancepic = ("promoted_lance.gif")
promoted_lanceimg = Image(promoted_lancepic)
promoted_pawnpic = ("promoted_pawn.gif")
promoted_pawnimg = Image(promoted_pawnpic)
promoted_rookpic = ("promoted_rook.gif")
promoted_rookimg = Image(promoted_rookpic)
promoted_silver_generalpic = ("promoted_silver_general.gif")
promoted_silver_generalimg = Image(promoted_silver_generalpic)
rookpic = ("rook.gif")
rookimg = Image(rookpic)
silver_generalpic = ("silver_general.gif")
silver_generalimg = Image(silver_generalpic)
emptypic = ("empty.gif")
emptyimg = Image(emptypic)

bishoprpic = ("bishopr.gif")
bishoprimg = Image(bishoprpic)
gold_generalrpic = ("gold_generalr.gif")
gold_generalrimg = Image(gold_generalrpic)
kingrpic = ("kingr.gif")
kingrimg = Image(kingrpic)
knightrpic = ("knightr.gif")
knightrimg = Image(knightrpic)
lancerpic = ("lancer.gif")
lancerimg = Image(lancerpic)
pawnrpic = ("pawnr.gif")
pawnrimg = Image(pawnrpic)
promoted_bishoprpic = ("promoted_bishopr.gif")
promoted_bishoprimg = Image(promoted_bishoprpic)
promoted_knightrpic = ("promoted_knightr.gif")
promoted_knightrimg = Image(promoted_knightrpic)
promoted_lancerpic = ("promoted_lancer.gif")
promoted_lancerimg = Image(promoted_lancerpic)
promoted_pawnrpic = ("promoted_pawnr.gif")
promoted_pawnrimg = Image(promoted_pawnrpic)
promoted_rookrpic = ("promoted_rookr.gif")
promoted_rookrimg = Image(promoted_rookrpic)
promoted_silver_generalrpic = ("promoted_silver_generalr.gif")
promoted_silver_generalrimg = Image(promoted_silver_generalrpic)
rookrpic = ("rookr.gif")
rookrimg = Image(rookrpic)
silver_generalrpic = ("silver_generalr.gif")
silver_generalrimg = Image(silver_generalrpic)
emptypic = ("empty.gif")
emptyimg = Image(emptypic)

w = Toplevel("Grid")
f = Frame(w, padding = 10); pack(f, expand=true, fill="both")

 # add to img Dict
imgDict = Dict(('_','_')=>emptyimg,('k','b')=>kingimg,('b','b')=>bishopimg,('g','b')=>gold_generalimg,
 ('n','b')=>knightimg,('l','b')=>lanceimg, ('B','b')=>promoted_bishopimg,('N','b')=>promoted_lanceimg,('P','b')=>promoted_pawnimg,
 ('R','b')=>promoted_rookimg,('S','b')=>promoted_silver_generalimg,('r','b')=>rookimg,('s','b')=>silver_generalimg,
 ('p','b')=>pawnimg,('k','w')=>kingrimg,('b','w')=>bishoprimg,('g','w')=>gold_generalrimg,
  ('n','w')=>knightrimg,('l','w')=>lancerimg, ('B','w')=>promoted_bishoprimg,('N','w')=>promoted_lancerimg,('P','w')=>promoted_pawnrimg,
  ('R','w')=>promoted_rookrimg,('S','w')=>promoted_silver_generalrimg,('r','w')=>rookrimg,('s','w')=>silver_generalrimg,
  ('p','w')=>pawnrimg)

pimg = Button(f, "",pawnimg)

#=bimg = Button(f, "",bishopimg)
gimg = Button(f, "",gold_generalimg)
nimg = Button(f, "",knightimg)
limg = Button(f, "",lanceimg)
bpimg = Button(f, "",promoted_bishopimg)
npimg = Button(f, "",promoted_knightimg)
lpimg = Button(f, "",promoted_lanceimg)
ppimg = Button(f, "",promoted_pawnimg)
rpimg = Button(f, "",promoted_rookimg)
spimg = Button(f, "",promoted_silver_generalimg)
rimg = Button(f, "",rookimg)
simg = Button(f, "",silver_generalimg)
emptypicimg = Button(f, "", emptyimg)

=#
for x in 1:16
  for y in 1:16
    grid(Button(f, "",imgDict[board[x,y]]),x,y)
  end
end
#start playing game

#end
end
#dispgfx()
#mini()
#emptybrdtest()
#chu()
#cd("../")
export dispgfx,mini

max_stars_repo_name: kinoroy/Shogi

max_issues_repo_name: kinoroy/Shulia

max_forks_repo_name: kinoroy/Shulia


text:
"""
    build_QP_JuMP_model(Q,R,A,B,N;...) -> JuMP.Model(...)
Return a `JuMP.jl` Model for the quadratic problem

min 1/2 ( sum_{i=1}^{N-1} s_i^T Q s + sum_{i=1}^{N-1} u^T R u + s_N^T Qf s_n  )
s.t. s_{i+1} = As_i + Bs_i for i = 1,..., N-1
Optional Arguments
- `Qf = []`: matrix multiplied by s_N in objective function (defaults to Q if not given)
- `c = zeros(N*size(Q,1) + N*size(R,1)`:  linear term added to objective funciton, c^T z
- `sl = fill(-Inf, size(Q,1))`: lower bound on state variables
- `su = fill(Inf,  size(Q,1))`: upper bound on state variables
- `ul = fill(-Inf, size(Q,1))`: lower bound on input variables
- `uu = fill(Inf,  size(Q,1))`: upper bound on input variables
- `s0 = []`: initial state of the first state variables
"""
function build_QP_JuMP_model(
        Q,R,A,B, N;
        s0 = [],
        sl = [],
        su = [],
        ul = [],
        uu = [],
        Qf = Q,
        E  = [],
        F  = [],
        gl = [],
        gu = [],
        S  = zeros(size(Q, 1), size(R, 1)),
        K  = zeros(size(R, 1), size(Q, 1))
        )

    ns = size(Q,1) # Number of states
    nu = size(R,1) # Number of inputs

    NS = 1:ns # set of states
    NN = 1:N # set of times
    NU = 1:nu # set of inputs

    model = Model(MadNLP.Optimizer) # define model

    @variable(model, s[NS, 0:N])     # define states
    @variable(model, u[NU, 0:(N-1)]) # define inputs

    if !iszero(K)
        @variable(model, v[NU, 0:(N-1)])
    end

    # Bound states/inputs
    if length(sl) > 0
        for i in NS
            for j in 0:N
                if sl[i] != -Inf
                    @constraint(model, s[i,j] >= sl[i])
                end
            end
        end
    end
    if length(su) > 0
        for i in NS
            for j in 0:N
                if su[i] != Inf
                    @constraint(model, s[i,j] <= su[i])
                end
            end
        end
    end
    if length(ul) > 0
        for i in NU
            for j in 0:(N-1)
                if ul[i] != -Inf
                    @constraint(model,  u[i,j] >= ul[i])
                end
            end
        end
    end
    if length(uu) > 0
        for i in NU
            for j in 0:(N-1)
                if uu[i] != Inf
                    @constraint(model, u[i,j] <= uu[i])
                end
            end
        end
    end

    if length(s0) >0
        for i in NS
            JuMP.fix(s[i,0], s0[i])
        end
    end

    # Give constraints from A, B, matrices
    @constraint(model, [t in 0:(N - 1), s1 in NS], s[s1, t + 1] == sum(A[s1, s2] * s[s2, t] for s2 in NS) + sum(B[s1, u1] * u[u1, t] for u1 in NU) )

    # Constraints for Kx + v = u
    if !iszero(K)
        for u1 in NU
            @constraint(model, [t in 0:(N - 1)], u[u1, t] == v[u1, t] + sum( K[u1, s1] * s[s1,t]  for s1 in NS))
        end
    end

    # Add E, F constraints
    if length(E) > 0
        for i in 1:size(E,1)
            @constraint(model,[t in 0:(N-1)], gl[i] <= sum(E[i, s1] * s[s1, t] for s1 in NS) + sum(F[i,u1] * u[u1, t] for u1 in NU))
            @constraint(model,[t in 0:(N-1)], gu[i] >= sum(E[i, s1] * s[s1, t] for s1 in NS) + sum(F[i,u1] * u[u1, t] for u1 in NU))
        end
    end

    # Give objective function as xT Q x + uT R u where x is summed over T and u is summed over T-1
    @objective(model,Min,  sum( 1/2 * Q[s1, s2]*s[s1,t]*s[s2,t] for s1 in NS, s2 in NS, t in 0:(N-1)) +
            sum( 1/2 * R[u1,u2] * u[u1, t] * u[u2,t] for t in 0:(N-1) , u1 in NU, u2 in NU) +
            sum( 1/2 * Qf[s1,s2] * s[s1,N] * s[s2, N]  for s1 in NS, s2 in NS) +
            sum( S[s1, u1] * s[s1, t] * u[u1, t] for s1 in NS, u1 in NU, t in 0:(N-1))
            )

    return model
end


text:
if is_unix()
    jt_parameters = string(dirname(Base.source_path()),"/../lib/default.parameters")
    const libwhisk_path=string(dirname(Base.source_path()),"/../deps/whisk/lib/whisk/libwhisk.so")

    const pre_train_path = string(dirname(Base.source_path()),"/../deps/quad_hourglass_64.mat")
else
    const libwhisk_path=string(dirname(Base.source_path()),"\\..\\deps\\whisk\\whisker\\lib\\whisk.dll")
    jt_parameters = string(dirname(Base.source_path()),"\\..\\lib\\default.parameters")

    const pre_train_path = string(dirname(Base.source_path()),"\\..\\deps\\quad_hourglass_64.mat")
end

#libwhisk = Libdl.dlopen(libwhisk_path,Libdl.RTLD_NOW)

if is_unix()
    #const ffmpeg_path = string(homedir(),"/Programs/ffmpeg/ffmpeg")
    #const ffprobe_path = string(homedir(),"/Programs/ffmpeg/ffprobe")
else
    #const ffmpeg_path = string(homedir(),"\\Documents\\ffmpeg\\bin\\ffmpeg")
    #const ffprobe_path = string(homedir(),"\\Documents\\ffmpeg\\bin\\ffprobe")
end

if is_unix()
    #const hourglass_path = string(homedir(),"/Programs/ffmpeg/ffmpeg")
else
    #const hourglass_path = string(homedir(),"\\Documents\\ffmpeg\\bin\\ffmpeg")
end


text:
# isstruct(::Type{T}) where T = !isbitstype(T) && !(T <: AbstractArray)
# isstruct(obj) = !isbits(obj) && !isa(obj, AbstractArray)
"Check if an object is of a struct type, i.e. not a number or array"
isstruct(::Type{T}) where T = !isempty(fieldnames(T))
isstruct(obj) = isstruct(typeof(obj))


text:
type LineSegPix
	x1::Cint
	x2::Cint
	y1::Cint
	y2::Cint
	active::Bool
end
#function LineSegPix(x1, x2, y1, y2, active)
#	x1 = 0; x2 = 0; y1 = 0; y2 = 0; active = false
#end

const NEWPOINT = 0
const MOVE = 1
const CLOSE = 2
const CENTER = 3
const REPAINT = 4

global poly_lastwhat = CLOSE

#-------------------------------------------------------------------------
# Desenha o poligono em rubber band.
#-------------------------------------------------------------------------
function polygon(handles::Handles, what::Integer, x::Integer, y::Integer)
	global poly_lastwhat

	line_seg = getappdata(handles.iup_canvas, "lineSeg")
	if (isnada(line_seg) || !line_seg.active) return end

	if (what == NEWPOINT)
		if (poly_lastwhat != CLOSE)
			cdCanvasLine(line_seg.x1, line_seg.y1, line_seg.x2, line_seg.y2);      # ...apaga a anterior e...
			cdCanvasLine(line_seg.x1, line_seg.y1, x, y);        # desenha a definitiva
		end
		line_seg.x1 = x;                        # novo segmento comeca no...
		line_seg.y1 = y;                        # fim do primeiro
	elseif (what == MOVE)
		if (poly_lastwhat == MOVE)
			cdCanvasLine(handles.cd_canvas, line_seg.x1, line_seg.y1, line_seg.x2, line_seg.y2);      # apaga o segmento velho
		end
		cdCanvasLine(handles.cd_canvas, line_seg.x1, line_seg.y1, x, y);     # desenha o novo
		line_seg.x2 = x;                        # e o novo se...
		line_seg.y2 = y;                        # torna velho
	elseif (what == REPAINT)
		cdCanvasLine(handles.cd_canvas, line_seg.x1, line_seg.y1, line_seg.x2, line_seg.y2);        # recupera o segmento perdido
		return                             # nao modifica lastwhat
	elseif (what == CLOSE)
		if (poly_lastwhat != CLOSE)
			cdLine(handles.cd_canvas, line_seg.x1, line_seg.y1, line_seg.x2, line_seg.y2);        # apaga o ultimo segmento
			# apaga o poligono temporario inteiro
			for i = 1:ctgc.num_points-1
				cdCanvasLine(handles.cd_canvas, ctgc.points[i].x, ctgc.points[i].y, ctgc.points[i+1].x, ctgc.points[i+1].y);
			end
		end
	end
	poly_lastwhat = what
	setappdata(handles.iup_canvas, "lineSeg", line_seg)
end

# ---------------------------------------------------------------------------------------------
function cmdDrawPoly(iup_canvas::Ptr{Ihandle})
	handles = guidata(iup_canvas)
	line_seg = LineSegPix(0, 0, 0, 0, true)

	setappdata(handles.iup_canvas, "lineSeg", line_seg)

	cdCanvasBackground(handles.cd_canvas, IUP_CD.CD_WHITE);
	cdCanvasClear(handles.cd_canvas);
	cdCanvasLineWidth(handles.cd_canvas, 3);
	cdCanvasLineStyle(handles.cd_canvas, IUP_CD.CD_CONTINUOUS);
	cdCanvasForeground(handles.cd_canvas, cdEncodeAlpha(IUP_CD.CD_DARK_MAGENTA, Char(128)))
	cdCanvasWriteMode(handles.cd_canvas, IUP_CD.CD_NOT_XOR)
	cdCanvasActivate(handles.cd_canvas)
	return IUP_DEFAULT
end

# ------------------------------------------------------------------------
function fMotionCB(hand::Ptr{Ihandle}, x::Int32, y::Int32, r::Ptr{UInt8})
	handles = guidata(hand)
	yp = convert(Ptr{Cint}, pointer([y]))
	cdCanvasUpdateYAxis(handles.cd_canvas, yp)
	y = unsafe_load(yp)
#@show(x,y)
	polygon(handles, MOVE, x, y)
	return IUP_DEFAULT
end

#-------------------------------------------------------------------------
# Function associated to the mouse buttons
#-------------------------------------------------------------------------
function fButtonCB(hand::Ptr{Ihandle}, b::Char, e::Integer, x::Integer, y::Integer, r::Ptr{UInt8})
	handles = guidata(hand)

	cdCanvasActivate(handles.cd_canvas)
	#cdCanvasWriteMode(handles.cd_canvas, IUP_CD.CD_NOT_XOR)
	cdCanvasForeground(handles.cd_canvas, convert(Clong, IUP_CD.CD_BLACK))
	cdCanvasLineStyle(handles.cd_canvas, IUP_CD.CD_CONTINUOUS)
	cdCanvasLineWidth(handles.cd_canvas, 1)
	cdCanvasClip(handles.cd_canvas, IUP_CD.CD_CLIPOFF)

	yp = convert(Ptr{Cint}, pointer([y]))
	cdCanvasUpdateYAxis(handles.cd_canvas, yp)
	y = unsafe_load(yp)
	x = Int32(x)

	set_current_point(handles.iup_canvas, [x,y])

	if (b == IUP_BUTTON1)		# Left button
		if (e != 0)				# button was pressed
			line_seg = getappdata(handles.iup_canvas, "lineSeg")
			if (isnada(line_seg)) return IUP_DEFAULT end
			line_seg.x1 = x
			line_seg.y1 = y
			line_seg.active = true
			setappdata(handles.iup_canvas, "lineSeg", line_seg)
		end
	end
	return IUP_DEFAULT
end


text:
# Various specialised operations using the Cholesky factorisation.

Xt_invA_X(A::Cholesky, x::AbstractVector) = sum(abs2, A.U' \ x)
function Xt_invA_X(A::Cholesky, X::AbstractVecOrMat)
    V = A.U' \ X
    return Symmetric(V'V)
end

Xt_invA_Y(X::AbstractVecOrMat, A::Cholesky, Y::AbstractVecOrMat) = (A.U' \ X)' * (A.U' \ Y)

diag_At_A(A::AbstractVecOrMat) = vec(sum(abs2.(A); dims=1))

function diag_At_B(A::AbstractVecOrMat, B::AbstractVecOrMat)
    @assert size(A) == size(B)
    return vec(sum(A .* B; dims=1))
end

diag_Xt_invA_X(A::Cholesky, X::AbstractVecOrMat) = diag_At_A(A.U' \ X)

function diag_Xt_invA_Y(X::AbstractMatrix, A::Cholesky, Y::AbstractMatrix)
    @assert size(X) == size(Y)
    return diag_At_B(A.U' \ X, A.U' \ Y)
end


text:
"""
    DataFlowTask(func,data,mode)

Create a task-like object similar to `Task(func)` which accesses `data` with
[`AccessMode`](@ref) `mode`.

When a `DataFlowTask` is created, the elements in its `data` field will be
checked against all other active `DataFlowTask` to determined if a dependency is
present based on a data-flow analysis. The resulting `Task` will then wait on
those dependencies.

A `DataFlowTask` behaves much like a Julia `Task`: you can call `wait(t)`,
`schedule(t)` and `fetch(t)` on it.

## See also: [`@dtask`](@ref), [`@dspawn`](@ref), [`@dasync`](@ref).
"""
mutable struct DataFlowTask
    data::Tuple
    access_mode::NTuple{<:Any,AccessMode}
    tag::Int
    priority::Float64
    label::String
    task::Task
    function DataFlowTask(code,data,mode::NTuple{N,AccessMode},priority=0,label="",sch=getscheduler()) where {N}
        @assert length(data) == N
        TASKCOUNTER[] += 1
        tj    = new(data,mode,TASKCOUNTER[],priority,label)
        addnode!(sch,tj,true)
        deps  = inneighbors(sch.dag,tj) |> copy
        tj.task = @task begin
            for ti in deps
                wait(ti)
            end
            # run the underlying code block and time its execution for logging
            t₀  = time_ns()
            res = code()
            t₁  = time_ns()
            tid = Threads.threadid()
            @trace "task_info $tid $t₀ $t₁ $(tj.tag) $(tj.label)"
            put!(sch.finished,tj)
            res
        end
        return tj
    end
end

"""
    const TASKCOUNTER::Ref{Int}

Global counter of created `DataFlowTask`s.
"""
const TASKCOUNTER = Ref(0)

"""
    data(t::DataFlowTask[,i])

Data accessed by `t`.
"""
data(t::DataFlowTask)        = t.data
data(t::DataFlowTask,i)      = t.data[i]

"""
    access_mode(t::DataFlowTask[,i])

How `t` accesses its data.

## See: [`AccessMode`](@ref)
"""
access_mode(t::DataFlowTask)   = t.access_mode
access_mode(t::DataFlowTask,i) = t.access_mode[i]

tag(t::DataFlowTask) = t.tag
tag(t) = t

Base.wait(t::DataFlowTask)  = wait(t.task)
Base.fetch(t::DataFlowTask) = fetch(t.task)

# the tag gives a total order of the tasks, with smaller tasks being assumed to
# have come before in a sequential execution of the program
Base.hash(t::DataFlowTask,h::UInt64)        = hash(t.tag,h)
Base.:(==)(a::DataFlowTask,b::DataFlowTask) = (a.tag == b.tag)
Base.:(<)(a::DataFlowTask,b::DataFlowTask)  = (a.tag < b.tag)

function Base.show(io::IO,t::DataFlowTask)
    if isdefined(t,:task)
        print(io, "DataFlowTask ($(t.task.state)) $(t.tag)")
    else
        print(io, "DataFlowTask (no Task created) $(t.tag)")
    end
end

Base.errormonitor(t::DataFlowTask) = errormonitor(t.task)

"""
    data_dependency(t1::DataFlowTask,t1::DataFlowTask)

Determines if there is a data dependency between `t1` and `t2` based on the data
they read from and write to.
"""
function data_dependency(ti::DataFlowTask, tj::DataFlowTask)
    # unpack and dispatch
    di,dj = data(ti), data(tj)
    mi,mj = access_mode(ti), access_mode(tj)
    _data_dependency(di,mi,dj,mj)
end

@noinline function _data_dependency(datai,modei,dataj,modej)
    for (di,mi) in zip(datai,modei)
        for (dj,mj) in zip(dataj,modej)
            mi == READ && mj == READ && continue
            if memory_overlap(di,dj)
                return true
            end
        end
    end
    return false
end

"""
    memory_overlap(di,dj)

Determine if data `di` and `dj` have overlapping memory in the sense that
mutating `di` can change `dj` (or vice versa). This function is used to build
the dependency graph between [`DataFlowTask`](@ref)s.

A generic version is implemented returning `true` (but printing a warning).
Users should overload this function for the specific data types used in the
arguments to allow for appropriate inference of data dependencies.
"""
function memory_overlap(di,dj)
    (isbits(di) || isbits(dj)) && return false
    @warn "memory_overlap(::$(typeof(di)),::$(typeof(dj))) not implemented. Defaulting to `true`"
    return true
end

"""
    macro dtask(expr,data,mode)

Create a `DataFlowTask` to execute `expr`, where `mode::NTuple{N,AccessMode}`
species how `data::Tuple{N,<:Any}` is accessed in `expr`. Note that the task is
not automatically scheduled for execution.

## See also: [`@dspawn`](@ref), [`@dasync`](@ref)
"""
macro dtask(expr,data,mode,p=0)
    :(DataFlowTask(
        ()->$(esc(expr)),
        $(esc(data)),
        $(esc(mode)),
        $(esc(p))
        )
    )
end


text:
import Base.show
import Base.convert
import Base.getindex

abstract Rule

typealias ActionType Union{Function, Void}

type Grammar
  rules::Dict{Symbol, Rule}
end

immutable Terminal <: Rule
  name::AbstractString
  value

  function Terminal(name::AbstractString, value)
    return new(name, value);
  end

  Terminal(value) = new("", value)
end

immutable ReferencedRule <: Rule
  name::AbstractString
  symbol::Symbol
  action::ActionType

  function ReferencedRule(name::AbstractString, symbol::Symbol, action)
    return new(name, symbol, action)
  end

  function ReferencedRule(name::AbstractString, symbol::Symbol)
    return new(name, symbol, nothing)
  end
end

immutable AndRule <: Rule
  name::AbstractString
  values::Array{Rule}
  action::ActionType

  function AndRule(name::AbstractString, values::Array{Rule}, action)
    return new(name, values, action)
  end
end

immutable OrRule <: Rule
  name::AbstractString
  values::Array{Rule, 1}
  action::ActionType

  function OrRule{T <: Rule}(name::AbstractString, rules::Array{T}, action::ActionType)
    return new(name, rules, action)
  end

  function OrRule(name::AbstractString, left::OrRule, right::OrRule, action::ActionType)
    return new(name, vcat(left.values, right.values), action)
  end

  function OrRule(name::AbstractString, left::Rule, right::Rule, action::ActionType)
    return new(name, [left, right], action)
  end

  function OrRule(name::AbstractString, left::OrRule, right::Rule, action::ActionType)
    return new(name, vcat(left.values, right), action)
  end

  function OrRule(name::AbstractString, left::Rule, right::OrRule, action::ActionType)
    return new(name, vcat(right.values, left), action)
  end

  function OrRule(name::AbstractString, left::OrRule, right::Terminal, action::ActionType)
    return new(name, vcat(left.values, right.value), action)
  end

  function OrRule(name::AbstractString, left::Terminal, right::OrRule, action::ActionType)
    return new(name, vcat(right.values, left.value), action)
  end

  function OrRule{T1, T2}(name::AbstractString, left::T1, right::T2, action::ActionType)
    return new(name, [left, right], action)
  end
end

immutable OneOrMoreRule <: Rule
  name::AbstractString
  value::Rule
  action::ActionType
end

immutable ZeroOrMoreRule <: Rule
  name::AbstractString
  value::Rule
  action::ActionType
end

immutable RangeRule <: Rule
  name::AbstractString
  range::UnitRange{Int64}
  action::ActionType

  function RangeRule(name::AbstractString, range::UnitRange{Int64}, action::ActionType)
    return new(name, range, action)
  end
end

immutable RepeatedRule <: Rule
  name::AbstractString
  range::UnitRange{Int64}
  value::Rule
  action::ActionType

  function RepeatedRule(name::AbstractString, range::RangeRule, value::Rule, action::ActionType)
    return new(name, range.range, value, action)
  end
end

immutable RegexRule <: Rule
  name::AbstractString
  value::Regex
  action::ActionType

  function RegexRule(name::AbstractString, value::Regex; action=nothing)
    return new(name, value, action)
  end
end

immutable OptionalRule <: Rule
  name::AbstractString
  value::Rule
  action::ActionType

  function OptionalRule(name::AbstractString, value::Rule)
    return new(name, value)
  end

  function OptionalRule(value::Rule)
    return new("", value)
  end
end

immutable ListRule <: Rule
  name::AbstractString
  entry::Rule
  delim::Rule
  action::ActionType

  function ListRule(name::AbstractString, entry::Rule, delim::Rule; action=nothing)
    return new(name, entry, delim, action)
  end
end

immutable FunctionRule <: Rule
  name::AbstractString
  fn::Symbol
  args::Array{Rule}

  function FunctionRule(name::AbstractString, fn::Symbol, args::Array{Rule})
    return new(name, fn, args)
  end
end

immutable ExprRule <: Rule
  name::AbstractString
  args::Array{Any, 1}

  function ExprRule(name::AbstractString, args::Array{Any, 1})
    return new(name, args)
  end
end

function show(io::IO, t::Terminal)
  print(io, "$(t.value)");
end

function show(io::IO, rule::AndRule)
  values = [string(r) for r in rule.values];
  joinedValues = join(values, " ");
  action = rule.action === nothing ? "" : "[$(rule.action)] "
  print(io, "($action$joinedValues)");
end

function show(io::IO, rule::OrRule)
  values = [string(r) for r in rule.values];
  joinedValues = join(values, "|");
  print(io, "($joinedValues)");
end

function show(io::IO, rule::OneOrMoreRule)
  print(io, "+($(rule.value))");
end

function show(io::IO, rule::ZeroOrMoreRule)
  print(io, "*($(rule.value))");
end

function show(io::IO, rule::RegexRule)
  print(io, "r($(rule.value.pattern))")
end

function convert{T}(::Type{Rule}, n::T)
  return Terminal(n);
end

function convert{T<:Rule}(::Type{Rule}, n::T)
  return n;
end

function convert{T}(::Type{Rule}, n::UnitRange{T})
  terminals = [Terminal(i) for i=(n.start):(n.stop)];
  return OrRule(terminals);
end

function parseDefinition(name::AbstractString, value::AbstractString, action::ActionType)
  return Terminal(name, value);
end

function parseDefinition(name::AbstractString, value::Char, action::ActionType)
  return Terminal(name, value);
end

function parseDefinition{T <: Number}(name::AbstractString, value::T, action::ActionType)
  return Terminal(name, value);
end

function parseDefinition(name::AbstractString, symbol::Symbol, action::ActionType)
  return ReferencedRule(name, symbol)
end

function parseDefinition(name::AbstractString, var::QuoteNode, action::ActionType)
  return var.value
end

function parseDefinition(name::AbstractString, regex::Regex, action::ActionType)
  # TODO: Need to do this to ensure we always match at the beginning,
  # but there should be a safer way to do this
  modRegex = Regex("^$(regex.pattern)")
  return RegexRule(name, modRegex)
end

type EmptyRule <: Rule
end

function parseDefinition(name::AbstractString, ex::Expr, action::ActionType)
  # if it's a macro (e.g. r"regex") then we want to expand it first
  if ex.head === :macrocall
    return parseDefinition(name, eval(ex))
  end

  if ex.args[1] === :|
    left = parseDefinition("$name.1", ex.args[2], nothing)
    right = parseDefinition("$name.2", ex.args[3], nothing)
    return OrRule(name, left, right, action)
  elseif ex.args[1] === :+
    # check if this is infix or prefix
    if length(ex.args) > 2
      # Addition can contain multiple entries
      values::Array{Rule} = [parseDefinition("$name.$i", arg, nothing) for (i, arg) in enumerate(ex.args[2:end])]
      return AndRule(name, values, action)
    else
      # it's prefix, so it maps to one or more rule
      return OneOrMoreRule(name, parseDefinition("$name.1", ex.args[2], nothing), action)
    end
  elseif ex.args[1] === :* && length(ex.args) == 2
    # it's a prefix, so it maps to zero or more rule
    return ZeroOrMoreRule(name, parseDefinition("$name.1", ex.args[2], nothing), action)
  elseif ex.args[1] == :^
    rule = ex.args[2]
    range = ex.args[3]
    return RepeatedRule(name, parseDefinition("$name.range", range, nothing), parseDefinition("$name.1", rule, nothing), action)
  elseif ex.args[1] == :?
    return OptionalRule(parseDefinition(name, ex.args[2], nothing), action)
  elseif ex.args[1] == :list
    entry = parseDefinition("$name.entry", ex.args[2], nothing)
    delim = parseDefinition("$name.delim", ex.args[3], nothing)
    return ListRule(name, entry, delim, action)
  elseif typeof(ex.args[1]) === Symbol
    args = [parseDefinition("$name.$i", arg, nothing) for (i, arg) in enumerate(ex.args[2:end])]
    return ExprRule(name, args)
  elseif ex.head == :(:)
    # a UnitRange
#     return OrRule(name, [Terminal(value) for value in (ex.args[1]):(ex.args[2])], nothing)
    return RangeRule(name, (ex.args[1]):(ex.args[2]), action)
  end

  println("?? $(ex.args)")
  return EmptyRule()
end

macro grammar(grammar_name::Symbol, ex::Expr)
  code = []
  push!(code, :(rules = Dict()))
  for definition in ex.args[2:2:end]
    if typeof(definition.args[1]) === Expr && definition.args[1].head === :ref
      name = Expr(:call, :string, Expr(:quote, definition.args[1].args[1]))
      ex = Expr(:quote, definition.args[2])
      action = Expr(:escape, definition.args[1].args[2])

      # rules[name] = parseDefinition(name, ex, action)
      push!(code, Expr(:(=), Expr(:ref, :rules, name),
                       Expr(:call, :parseDefinition, name, ex, action)))
    else
      name = Expr(:call, :string, Expr(:quote, definition.args[1]))
      ex = Expr(:quote, definition.args[2])

      # rules[name] = parseDefinition(name, ex, nothing)
      push!(code, Expr(:(=), Expr(:ref, :rules, name),
                       Expr(:call, :parseDefinition, name, ex, nothing)))
    end
  end

  # grammar_name = Grammar(rules)
  push!(code, :($(esc(grammar_name)) = Grammar(rules)))

  # group all code into a single block
  return Expr(:block, code...)
end

function *(rule::Rule) end
function ?(rule::Rule) end
function list(entry::Rule, delim::Rule) end

#end

max_stars_repo_name: rcnlee/GrammaticalEvolution

max_issues_repo_name: rcnlee/GrammaticalEvolution

max_forks_repo_name: rcnlee/GrammaticalEvolution


text:
"""
```
newserver(dsn, name, addr, port::Integer=-1)
```

Create a new server in the `servers` table.
"""
function newserver(dsn, name, address, port::Integer=-1)
    if port > -1
        ODBC.execute!(dsn, """
            INSERT INTO servers VALUES ('$name', '$address', '$port');
        """)
    else
        ODBC.execute!(dsn, """
            INSERT INTO servers VALUES ('$name', '$address');
        """)
    end
end

"""
```
updateserver(dsn, name; kwargs...)
```

Update a server in the `servers` table using keyword arguments (`name`, `address`,
`port`).
"""
function updateserver(dsn, name; kwargs...)
    isempty(kwargs) && return
    pstr = reduce((a,b)->a*","*b, "$k = '$v'" for (k,v) in kwargs)
    for (k,v) in kwargs
        ODBC.execute!(dsn, "UPDATE servers SET "*pstr*" WHERE name = '$name';")
    end
end

"""
```
deleteserver(dsn, name)
```

Remove a server from the `servers` table by passing its `name`.
"""
function deleteserver(dsn, name)
    ODBC.execute!(dsn, "DELETE FROM servers WHERE name='$name';")
end

"""
```
listservers(dsn, name)
```

List all servers in the `servers` table.
"""
function listservers(dsn)
    ODBC.query(dsn, "SELECT * FROM servers;")
end


text:
using Maker
using Base.Test

x = [ 3.14159   6.28319   9.42478
      12.5664   15.708    18.8496
      21.9911   25.1327   28.2743 ]

writecsv("b.csv", x)

Maker.variable("a") do
    println("Generating `a`.")
    pi
end

Maker.variable("b", "b.csv") do
    println("Reading `b`.")
    readcsv("b.csv")
end

Maker.file("b.csv")

Maker.variable("c", ["a", "b"]) do
    println("Calculating `c`.")
    a * b
end

make("a")
make("b")
make("c")

@test a ≈ pi
@test b ≈ x
@test c ≈ pi * x

# redefine `a`
Maker.variable("a") do
    println("Regenerating `a`.")
    2pi
end

make("c", verbose = true)

@test a ≈ 2pi
@test b ≈ x
@test c ≈ 2pi * x

# redefine `a` again:

Maker.variable("a") do
    println("Generating `a`.")
    pi
end

make("a", verbose=true)

@test a ≈ pi
@test c ≈ 2pi * x

make("c", verbose=true)

@test a ≈ pi
@test c ≈ pi * x

# change `a`

a = -pi

make("c")

@test a ≈ pi
@test c ≈ pi * x

rm("b.csv")


text:
######################################################################
# pto_multi.jl
#
# for multi-agent stuff
######################################################################

function pto_trajectory(em::ErgodicManager, vtm::Vector{TrajectoryManager}; verbose::Bool=true, logging::Bool=false, max_iters::Int=100, es_crit::Float64=0.0, dd_crit::Float64=1e-6)
	xd0,ud0 = initialize(em, vtm)
	pto_trajectory(em, vtm, xd0, ud0; verbose=verbose, logging=logging, max_iters=max_iters, es_crit=es_crit, dd_crit = dd_crit)
end

function pto_trajectory(em::ErgodicManager, vtm::Vector{TrajectoryManager}, xd0::VVF, ud0::VVF; verbose::Bool=true, logging::Bool=false, max_iters::Int=100, es_crit::Float64=0.0, dd_crit::Float64=1e-6)

	# creating a special trajectory manager with group dynamics
	num_agents = length(vtm)
	tm = deepcopy(vtm[1]) # super hacky...
	darr = Dynamics[]
	Rarr = VMF()
	for j = 1:num_agents
		push!(darr, vtm[j].dynamics)
		push!(Rarr, vtm[j].R)
	end
	tm.dynamics = GroupDynamics(darr)
	tm.Qn = eye(tm.dynamics.n, tm.dynamics.n)
	tm.Rn = eye(tm.dynamics.m, tm.dynamics.m)
	dims = 2*ones(Int, num_agents)
	dims[1] = 1
	tm.R = cat(dims, Rarr...)

	# let's not overwrite the initial trajectories
	xd = deepcopy(xd0)
	ud = deepcopy(ud0)
	N = tm.N

	# matrices for gradients
	ad = zeros(tm.dynamics.n, N+1)
	bd = zeros(tm.dynamics.m, N)

	# prepare for logging if need be
	if logging
		outfile = open("temp.csv", "w")
		save(outfile, xd)
	end

	if verbose; print_header(); end
	i = 1
	not_finished = true
	es = 0.; cs = 0.; ts = 0.; dd = 0.; step_size = 0.; es_diff=0.0
	es_prev = 0.0
	es_count = 1
	while not_finished

		# determine gradients used in optimization
		gradients!(ad, bd, em, vtm, xd, ud)

		# find gains K and descent direction (zd, vd) using LQ
		A, B = linearize(tm.dynamics, xd, ud, tm.h)
		K, C = LQ(A, B, ad, bd, tm.Qn, tm.Rn, tm.N)
		zd, vd = apply_LQ_gains(A, B, K, C)

		# determine step size and descend
		step_size = get_step_size(tm.descender, em, tm, xd, ud, zd, vd, ad, bd, K, i)

		# descend and project
		xd, ud = project(em, tm, K, xd, ud, zd, vd, step_size)

		# compute statistics and report
		es, cs, ts = all_scores(em, tm, xd, ud)
		dd = directional_derivative(ad, bd, zd, vd)
		if verbose; step_report(i, es, cs, ts, dd, step_size); end
		if logging; save(outfile, xd); end

		# check convergence
		i += 1
		es_count = abs(es - es_prev) < 1e-7 ? es_count + 1 : 0
		es_prev = es
		not_finished = check_convergence(es,es_crit,i,max_iters,dd,dd_crit,verbose, es_count)
	end

	# now that we are done, print a special finished report
	if verbose
		print_header()
		if verbose; step_report(i-1, es, cs, ts, dd, step_size); end
	end

	if logging; close(outfile); end

	return xd, ud
end


text:
using Test
using Distributions: Categorical, kldivergence, expectation, Normal
@test kldivergence(Categorical([0.0, 0.1, 0.9]), Categorical([0.1, 0.1, 0.8])) ≥ 0
@test kldivergence(Categorical([0.0, 0.1, 0.9]), Categorical([0.1, 0.1, 0.8])) ≈
    kldivergence([0.0, 0.1, 0.9], [0.1, 0.1, 0.8])
@test expectation(Normal(0.0, 1.0), identity, 1e-10) ≤ 1e-9


text:
using CaratheodorySolver
using Test

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


text:
function_dummy_v(t, q, v) = nothing
function_dummy_v(t, q, p, v) = nothing

"""
    promote_tspan(tspan)
Convert the `tspan` field of a `GeometricProblem` to a `(tmin, tmax)` tuple, where both
elements are of the same type.
"""
promote_tspan((t1,t2)::Tuple{T,S}) where {T,S} = promote(t1, t2)
promote_tspan(tspan::Number) = (zero(tspan),tspan)
promote_tspan(tspan::Nothing) = (nothing,nothing)
promote_tspan(tspan::AbstractArray) = length(tspan) == 2 ? promote_tspan((first(tspan),last(tspan))) : throw(error("The length of tspan must be two (and preferably, tspan should be a tuple, i.e. (0.0,1.0))."))

function promote_tspan_and_tstep((t1,t2)::Tuple, Δt::Number)
    t = promote(t1, t2, Δt)
    return (t[1], t[2]), t[3]
end

parameter_types(params::NullParameters) = params
parameter_types(params::NamedTuple) = NamedTuple{keys(params)}(typeof.(values(params)))

function initial_multiplier(q₀::AbstractVector{DT}, λ₀::AbstractVector{DT}) where {DT <: Number}
    zero(λ₀)
end

function initial_multiplier(q₀::AbstractVector{DT}, λ₀::AbstractVector{AT}) where {DT <: Number, AT <: AbstractArray{DT}}
    zero(λ₀[begin])
end

function initial_multiplier(q₀::AbstractVector{AT}, λ₀::AbstractVector{DT}) where {DT <: Number, AT <: AbstractArray{DT}}
    [zero(λ₀) for i in eachindex(q₀)]
end

function initial_multiplier(q₀::AbstractVector{AT}, λ₀::AbstractVector{AT}) where {DT <: Number, AT <: AbstractArray{DT}}
    [zero(λ₀[begin]) for i in eachindex(q₀)]
end

function symplectic_matrix(::Type{DT}, d::Int) where {DT}
    ω = zeros(DT, 2d, 2d)

    for i in 1:d
        ω[i, d+i] = +1
        ω[d+i, i] = -1
    end

    return ω
end

function symplectic_matrix(::Number, q::AbstractVector{DT}, p::AbstractVector{DT}) where {DT}
    @assert length(q) == length(p)
    symplectic_matrix(DT, length(q))
end


text:
# Test if tf broadcaster works correctly
using RobotOS
@rosimport std_msgs.msg: Header, Bool
@rosimport geometry_msgs.msg: Transform, TransformStamped, Vector3, Quaternion
rostypegen(@__MODULE__)
import .std_msgs.msg: Header, BoolMsg
import .geometry_msgs.msg: Transform, TransformStamped, Vector3, Quaternion

using ROSTransforms.tf2_ros
using Test

init_node("broadcaster", anonymous=true) # delete
tb = TransformBroadcaster()

# Build the success callback function
success = false
function cb(msg::BoolMsg)
    global success = msg.data
end
sub1 = Subscriber{BoolMsg}("/success", cb, queue_size=10)

r = Rate(10.0)
for i ∈ 1:10000
    tf_correct = TransformStamped(Header(0, RobotOS.now(), "parent_link"),
                                  "child_link",
                                  Transform(Vector3(1., 2., 3.),
                                            Quaternion(0, 0, 0, 1.))
                                  )

    sendTransform(tb, tf_correct)

    success && break  # Break if the listener heard the broadcaster
    rossleep(r)
end

@testset "TransformBroadcaster" begin
    @test success  # Success if listener heard
end