text:
# syntax: proto3
using ProtoBuf
import ProtoBuf.meta

mutable struct FunctionDef_AttrEntry <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FunctionDef_AttrEntry(; kwargs...)
        obj = new(meta(FunctionDef_AttrEntry), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FunctionDef_AttrEntry (mapentry)
const __meta_FunctionDef_AttrEntry = Ref{ProtoMeta}()
function meta(::Type{FunctionDef_AttrEntry})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FunctionDef_AttrEntry)
            __meta_FunctionDef_AttrEntry[] = target = ProtoMeta(FunctionDef_AttrEntry)
            allflds = Pair{Symbol,Union{Type,String}}[:key => AbstractString, :value => AttrValue]
            meta(target, FunctionDef_AttrEntry, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FunctionDef_AttrEntry[]
    end
end
function Base.getproperty(obj::FunctionDef_AttrEntry, name::Symbol)
    if name === :key
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :value
        return (obj.__protobuf_jl_internal_values[name])::AttrValue
    else
        getfield(obj, name)
    end
end

mutable struct FunctionDef_ArgAttrs_AttrEntry <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FunctionDef_ArgAttrs_AttrEntry(; kwargs...)
        obj = new(meta(FunctionDef_ArgAttrs_AttrEntry), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FunctionDef_ArgAttrs_AttrEntry (mapentry)
const __meta_FunctionDef_ArgAttrs_AttrEntry = Ref{ProtoMeta}()
function meta(::Type{FunctionDef_ArgAttrs_AttrEntry})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FunctionDef_ArgAttrs_AttrEntry)
            __meta_FunctionDef_ArgAttrs_AttrEntry[] = target = ProtoMeta(FunctionDef_ArgAttrs_AttrEntry)
            allflds = Pair{Symbol,Union{Type,String}}[:key => AbstractString, :value => AttrValue]
            meta(target, FunctionDef_ArgAttrs_AttrEntry, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FunctionDef_ArgAttrs_AttrEntry[]
    end
end
function Base.getproperty(obj::FunctionDef_ArgAttrs_AttrEntry, name::Symbol)
    if name === :key
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :value
        return (obj.__protobuf_jl_internal_values[name])::AttrValue
    else
        getfield(obj, name)
    end
end

mutable struct FunctionDef_ArgAttrs <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FunctionDef_ArgAttrs(; kwargs...)
        obj = new(meta(FunctionDef_ArgAttrs), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FunctionDef_ArgAttrs
const __meta_FunctionDef_ArgAttrs = Ref{ProtoMeta}()
function meta(::Type{FunctionDef_ArgAttrs})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FunctionDef_ArgAttrs)
            __meta_FunctionDef_ArgAttrs[] = target = ProtoMeta(FunctionDef_ArgAttrs)
            allflds = Pair{Symbol,Union{Type,String}}[:attr => Base.Dict{AbstractString,AttrValue}]
            meta(target, FunctionDef_ArgAttrs, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FunctionDef_ArgAttrs[]
    end
end
function Base.getproperty(obj::FunctionDef_ArgAttrs, name::Symbol)
    if name === :attr
        return (obj.__protobuf_jl_internal_values[name])::Base.Dict{AbstractString,AttrValue}
    else
        getfield(obj, name)
    end
end

mutable struct FunctionDef_ArgAttrEntry <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FunctionDef_ArgAttrEntry(; kwargs...)
        obj = new(meta(FunctionDef_ArgAttrEntry), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FunctionDef_ArgAttrEntry (mapentry)
const __meta_FunctionDef_ArgAttrEntry = Ref{ProtoMeta}()
function meta(::Type{FunctionDef_ArgAttrEntry})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FunctionDef_ArgAttrEntry)
            __meta_FunctionDef_ArgAttrEntry[] = target = ProtoMeta(FunctionDef_ArgAttrEntry)
            allflds = Pair{Symbol,Union{Type,String}}[:key => UInt32, :value => FunctionDef_ArgAttrs]
            meta(target, FunctionDef_ArgAttrEntry, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FunctionDef_ArgAttrEntry[]
    end
end
function Base.getproperty(obj::FunctionDef_ArgAttrEntry, name::Symbol)
    if name === :key
        return (obj.__protobuf_jl_internal_values[name])::UInt32
    elseif name === :value
        return (obj.__protobuf_jl_internal_values[name])::FunctionDef_ArgAttrs
    else
        getfield(obj, name)
    end
end

mutable struct FunctionDef_ResourceArgUniqueIdEntry <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FunctionDef_ResourceArgUniqueIdEntry(; kwargs...)
        obj = new(meta(FunctionDef_ResourceArgUniqueIdEntry), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FunctionDef_ResourceArgUniqueIdEntry (mapentry)
const __meta_FunctionDef_ResourceArgUniqueIdEntry = Ref{ProtoMeta}()
function meta(::Type{FunctionDef_ResourceArgUniqueIdEntry})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FunctionDef_ResourceArgUniqueIdEntry)
            __meta_FunctionDef_ResourceArgUniqueIdEntry[] = target = ProtoMeta(FunctionDef_ResourceArgUniqueIdEntry)
            allflds = Pair{Symbol,Union{Type,String}}[:key => UInt32, :value => UInt32]
            meta(target, FunctionDef_ResourceArgUniqueIdEntry, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FunctionDef_ResourceArgUniqueIdEntry[]
    end
end
function Base.getproperty(obj::FunctionDef_ResourceArgUniqueIdEntry, name::Symbol)
    if name === :key
        return (obj.__protobuf_jl_internal_values[name])::UInt32
    elseif name === :value
        return (obj.__protobuf_jl_internal_values[name])::UInt32
    else
        getfield(obj, name)
    end
end

mutable struct FunctionDef_RetEntry <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FunctionDef_RetEntry(; kwargs...)
        obj = new(meta(FunctionDef_RetEntry), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FunctionDef_RetEntry (mapentry)
const __meta_FunctionDef_RetEntry = Ref{ProtoMeta}()
function meta(::Type{FunctionDef_RetEntry})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FunctionDef_RetEntry)
            __meta_FunctionDef_RetEntry[] = target = ProtoMeta(FunctionDef_RetEntry)
            allflds = Pair{Symbol,Union{Type,String}}[:key => AbstractString, :value => AbstractString]
            meta(target, FunctionDef_RetEntry, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FunctionDef_RetEntry[]
    end
end
function Base.getproperty(obj::FunctionDef_RetEntry, name::Symbol)
    if name === :key
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :value
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    else
        getfield(obj, name)
    end
end

mutable struct FunctionDef_ControlRetEntry <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FunctionDef_ControlRetEntry(; kwargs...)
        obj = new(meta(FunctionDef_ControlRetEntry), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FunctionDef_ControlRetEntry (mapentry)
const __meta_FunctionDef_ControlRetEntry = Ref{ProtoMeta}()
function meta(::Type{FunctionDef_ControlRetEntry})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FunctionDef_ControlRetEntry)
            __meta_FunctionDef_ControlRetEntry[] = target = ProtoMeta(FunctionDef_ControlRetEntry)
            allflds = Pair{Symbol,Union{Type,String}}[:key => AbstractString, :value => AbstractString]
            meta(target, FunctionDef_ControlRetEntry, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FunctionDef_ControlRetEntry[]
    end
end
function Base.getproperty(obj::FunctionDef_ControlRetEntry, name::Symbol)
    if name === :key
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :value
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    else
        getfield(obj, name)
    end
end

mutable struct FunctionDef <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FunctionDef(; kwargs...)
        obj = new(meta(FunctionDef), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FunctionDef
const __meta_FunctionDef = Ref{ProtoMeta}()
function meta(::Type{FunctionDef})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FunctionDef)
            __meta_FunctionDef[] = target = ProtoMeta(FunctionDef)
            fnum = Int[1,5,7,8,3,4,6]
            allflds = Pair{Symbol,Union{Type,String}}[:signature => OpDef, :attr => Base.Dict{AbstractString,AttrValue}, :arg_attr => Base.Dict{UInt32,FunctionDef_ArgAttrs}, :resource_arg_unique_id => Base.Dict{UInt32,UInt32}, :node_def => Base.Vector{NodeDef}, :ret => Base.Dict{AbstractString,AbstractString}, :control_ret => Base.Dict{AbstractString,AbstractString}]
            meta(target, FunctionDef, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FunctionDef[]
    end
end
function Base.getproperty(obj::FunctionDef, name::Symbol)
    if name === :signature
        return (obj.__protobuf_jl_internal_values[name])::OpDef
    elseif name === :attr
        return (obj.__protobuf_jl_internal_values[name])::Base.Dict{AbstractString,AttrValue}
    elseif name === :arg_attr
        return (obj.__protobuf_jl_internal_values[name])::Base.Dict{UInt32,FunctionDef_ArgAttrs}
    elseif name === :resource_arg_unique_id
        return (obj.__protobuf_jl_internal_values[name])::Base.Dict{UInt32,UInt32}
    elseif name === :node_def
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{NodeDef}
    elseif name === :ret
        return (obj.__protobuf_jl_internal_values[name])::Base.Dict{AbstractString,AbstractString}
    elseif name === :control_ret
        return (obj.__protobuf_jl_internal_values[name])::Base.Dict{AbstractString,AbstractString}
    else
        getfield(obj, name)
    end
end

mutable struct GradientDef <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function GradientDef(; kwargs...)
        obj = new(meta(GradientDef), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct GradientDef
const __meta_GradientDef = Ref{ProtoMeta}()
function meta(::Type{GradientDef})
    ProtoBuf.metalock() do
        if !isassigned(__meta_GradientDef)
            __meta_GradientDef[] = target = ProtoMeta(GradientDef)
            allflds = Pair{Symbol,Union{Type,String}}[:function_name => AbstractString, :gradient_func => AbstractString]
            meta(target, GradientDef, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_GradientDef[]
    end
end
function Base.getproperty(obj::GradientDef, name::Symbol)
    if name === :function_name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :gradient_func
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    else
        getfield(obj, name)
    end
end

mutable struct FunctionDefLibrary <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FunctionDefLibrary(; kwargs...)
        obj = new(meta(FunctionDefLibrary), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FunctionDefLibrary
const __meta_FunctionDefLibrary = Ref{ProtoMeta}()
function meta(::Type{FunctionDefLibrary})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FunctionDefLibrary)
            __meta_FunctionDefLibrary[] = target = ProtoMeta(FunctionDefLibrary)
            allflds = Pair{Symbol,Union{Type,String}}[:_function => Base.Vector{FunctionDef}, :gradient => Base.Vector{GradientDef}]
            meta(target, FunctionDefLibrary, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FunctionDefLibrary[]
    end
end
function Base.getproperty(obj::FunctionDefLibrary, name::Symbol)
    if name === :_function
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{FunctionDef}
    elseif name === :gradient
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{GradientDef}
    else
        getfield(obj, name)
    end
end

export FunctionDefLibrary, FunctionDef_AttrEntry, FunctionDef_ArgAttrs_AttrEntry, FunctionDef_ArgAttrs, FunctionDef_ArgAttrEntry, FunctionDef_ResourceArgUniqueIdEntry, FunctionDef_RetEntry, FunctionDef_ControlRetEntry, FunctionDef, GradientDef
# mapentries: "FunctionDef_AttrEntry" => ("AbstractString", "AttrValue"), "FunctionDef_ArgAttrEntry" => ("UInt32", "FunctionDef_ArgAttrs"), "FunctionDef_ResourceArgUniqueIdEntry" => ("UInt32", "UInt32"), "FunctionDef_RetEntry" => ("AbstractString", "AbstractString"), "FunctionDef_ControlRetEntry" => ("AbstractString", "AbstractString"), "FunctionDef_ArgAttrs_AttrEntry" => ("AbstractString", "AttrValue")


text:
function _eval_string(x::K_)
    if xt(x) != KC
        return krr("type")
    end
    v = try
        eval(parse(xp(x)))
    catch err
        return krr(string(err))
    end
    p = try
        K_new(v)
    catch err
        return krr(string("K_new:", err))
    end
    p
end

const _eval_string_c = cfunction(_eval_string, K_, (K_, ))

ext: jl


text:
#unit-operations.jl
#other useful operations on unums.

#test __resolve_subnormal.
#takes a subnormal number and makes it normal, or the smallest subnormal class
#as makes most sense for that number.

#example:  0 1 0 0 is unum(0.5) in all contexts, and this is the same as:
#          01 0 1 0 in most unums.

#first demonstrate that the two representations (the subnormal and the normal) are
#equivalent.
x = Unum{4,6}(z64, t64, z16, z16, z16)
Unums.resolve_degenerates!(x)
@test calculate(x) == calculate(Unum{4,6}(z64, t64, z16, z16, z16))
@test x.fsize == z16
@test x.esize == o16
@test x.flags == z16
@test x.fraction == z64
@test x.exponent == o64
#note we can't use the equality operator testnig because the equality operator
#will engage the __resolve_subnormal function itself.

#repeat the exercise in a VarInt unum.
x = Unum{4,8}(z64, [t64, z64, z64, z64], z16, z16, z16)
Unums.resolve_degenerates!(x)
#@test calculate(x) == calculate(u)  #NB "calculate" doesn't currently work on superint unums.
@test x.fsize == z16
@test x.esize == o16
@test x.flags == z16
@test x.fraction.a == [z64, z64, z64, z64]
@test x.exponent == o64

#repeat the exercise in a very small unum.
x = Unum{2,2}(z64, t64, z16, z16, z16)
Unums.resolve_degenerates!(x)
@test calculate(x) == calculate(Unum{2,2}(z64, t64, z16, z16, z16))
@test x.fsize == z16
@test x.esize == o16
@test x.flags == z16
@test x.fraction == z64
@test x.exponent == o64

#=
#second example:  Take a unum at the edge of smallness and show that we can
#resolve this into the apropriate even smaller subnormal number.
x = Unum{2,4}(UInt16(15), z16, z16, 0x0001_0000_0000_0000, z64)
Unums.__resolve_subnormal!(x)
@test calculate(x) == calculate(UInt16(15), z16, z16, 0x0001_0000_0000_0000, z64)
@test x.exponent == 0
=#

@test Unums.inner_ulp(Unum{0,0}(2)) == Unums.make_ulp!(Unum{0,0}(1))
@test Unums.inner_ulp(Unum{2,2}(o64, z64, z16, z16, z16)) == Unum{2,2}(o64, 0xF000_0000_0000_0000, o16, o16, 0x0003)
@test Unums.inner_ulp(Unum{2,4}(o64, z64, z16, z16, z16)) == Unum{2,4}(o64, 0xFFFF_0000_0000_0000, o16, o16, 0x000F)
@test Unums.inner_ulp(Unum{2,4}(o64, z64, z16, 0x0003, z16)) == Unum{2,4}(z64, 0xFFFF_0000_0000_0000, o16, 0x0003, 0x000F)

#error discovered 24 oct 2016
x = Unum{4,7}(0x0000000000000001, UInt64[0x0000000000000000,0x0000000000000000], 0x0003, 0x0000, 0x007F)
z = Unums.outer_exact(x)
@test z == Unum{4,7}(0x0000000000000001, UInt64[0x0000000000000000,0x0000000000000001], 0x0002, 0x0000, 0x007F)
@test z.fsize == 0x007F

max_stars_repo_name: REX-Computing/unumjl

max_issues_repo_name: REX-Computing/unumjl

max_forks_repo_name: REX-Computing/unumjl


text:
using Revise

envnames = ["ab", "cpg", "mc"]

# make directories to store log files
_ckmkdir(f) = isdir(f) == false && mkdir(f)
_ckmkdir("log")
for envname in envnames
    _ckmkdir("log/"*envname)
end

#--------------- for 4 seed numbers ---------------------#
seednum = 1234
include("scripts/lc3_acrobot.jl")
include("scripts/lc3_cartpole.jl")
include("scripts/lc3_mountaincar.jl")
seednum = 2345
include("scripts/lc3_acrobot.jl")
include("scripts/lc3_cartpole.jl")
include("scripts/lc3_mountaincar.jl")
seednum = 3456
include("scripts/lc3_acrobot.jl")
include("scripts/lc3_cartpole.jl")
include("scripts/lc3_mountaincar.jl")
seednum = 4567
include("scripts/lc3_acrobot.jl")
include("scripts/lc3_cartpole.jl")
include("scripts/lc3_mountaincar.jl")

#--------------- compute the last results ---------------#

for envname in envnames
    # reading data
    d1 = read("log/"*envname*"/"*envname*".jlso", JLSOFile)
    d2 = read("log/"*envname*"/"*envname*"_1.jlso", JLSOFile)
    d3 = read("log/"*envname*"/"*envname*"_2.jlso", JLSOFile)
    d4 = read("log/"*envname*"/"*envname*"_3.jlso", JLSOFile)
    # extracting reward data to vector
    reward_1 = Vector(d1[:logs][:algstate][:traj_reward])
    reward_2 = Vector(d2[:logs][:algstate][:traj_reward])
    reward_3 = Vector(d3[:logs][:algstate][:traj_reward])
    reward_4 = Vector(d4[:logs][:algstate][:traj_reward])
    lenalg = length(reward_1)
    movemean = zeros(lenalg); movestdm = zeros(lenalg)
    # 5000 window average and across four random seeds
    timestep = 200
    for i in 1:lenalg
        p = 0.
        for j in max(1,(i-Int(5000/timestep)+1)):i
            p += 1.
            movemean[i] += reward_1[j]; movemean[i] += reward_2[j]; movemean[i] += reward_3[j]; movemean[i] += reward_4[j];
            movestdm[i] += reward_1[j]^2; movestdm[i] += reward_2[j]^2; movestdm[i] += reward_3[j]^2; movestdm[i] += reward_4[j]^2;
        end
        movemean[i] /= (p * 4)
        movestdm[i] /= (p * 4)
    end
    reward_m = movemean; reward_s = sqrt.(movestdm - movemean.^2)
    finalm = reward_m[end]; finals = reward_s[end]

    println("LC3 for $envname -> final mean: $finalm  final std: $finals")
end


text:
## Monomial
"""
    Monomial(exponents)

A `Monomial` function is a product of powers of variables with nonnegative
integer exponents.
```math
x_1^{p_1} * x_2^{p_2} *\\cdots * x_n^{p_n}
```
The `Monomial` is defined using a vector of integers `exponents`.
This vector contains the correspondent exponents ``p``
for all the inputs from `1` to `n`.
"""
struct Monomial <: Basis
    exponents::Vector{Int}
    n::Int
end

# Constructor
function Monomial(exponents::Vector{Int})
    n = length(exponents)
    Monomial(exponents, n)
end

# evaluate: Vector -> scalar
function evaluate(X::Vector{Float64}, monomial::Monomial)
    y = 1.0
    @inbounds @fastmath @simd for i = 1:monomial.n
        y *= X[i]^monomial.exponents[i]
    end
    return y
end

# evaluate!: Vector of Vectors -> Vector
function evaluate!(
        Y::Vector{Float64}, X::Vector{Vector{Float64}}, monomial::Monomial,
        N::Int, p::Int, update!::Function=identity!, args::Tuple=())

    @inbounds for i = 1:N
        Y[i] = 1.0
    end
    @inbounds for i = 1:p
        if monomial.exponents[i] == 1
            update!(X, i, N, args...)
            x = X[i]
            @simd for j = 1:N
                Y[j] *= x[j]
            end
        elseif monomial.exponents[i] > 0
            update!(X, i, N, args...)
            x = X[i]
            @simd for j = 1:N
                Y[j] *= x[j]^monomial.exponents[i]
            end
        end
    end
end

## Generate Monomials
function generate_all(::Type{Monomial}, n::Int, order::Int;)
    n_monomials = binomial(n+order-1, n-1)
    monomials = Vector{Monomial}(n_monomials)
    for (i, c) in enumerate(combinations(1:(n+order-1), n-1))
        combin = [0; c-collect(1:(n-1)); order]
        monomials[i] = Monomial(diff(combin))
    end
    return monomials
end

function generate_all(::Type{Monomial}, n::Int, order_list; kwargs...)
    vcat([generate_all(Monomial, n, order; kwargs...) for order in order_list]...)
end

# Print Monomial
function function_display(monomial::Monomial, names::Vector{String})
    str =""
    first_term = true
    for i = 1:monomial.n
        exp = monomial.exponents[i]
        if exp == 0
            continue
        end
        if ~first_term
            str = string(str, " * ")
        end
        first_term = false
        if exp == 1
            str = string(str, names[i])
        else
            str = string(str, names[i], "^", exp)
        end
    end
    return str
end

# Function Compare Monomials
Base.isequal(x::Monomial, y::Monomial) = x.exponents == y.exponents

# Check if contains input
function contains_inputs(m::Monomial, list_of_inputs::BitVector)
    return all(m.exponents[list_of_inputs] .== 0)
end


text:
function build_js_string(options::Options, swagger_doc::Union{Dict{String, Any}, Nothing})::String
    swagger_options = _options_to_json(options, swagger_doc)
    return """
        window.onload = function() {
            let url = window.location.search.match(/url=([^&]+)/);
            if (url && url.length > 1) {
                url = decodeURIComponent(url[1]);
            } else {
                url = window.location.origin;
            }
            const options = $(swagger_options)
            url = options.swaggerUrl || url
            const customOptions = options.customOptions
            const swaggerOptions = {
                spec: options.swaggerDoc,
                url: url,
                urls: options.swaggerUrls,
                dom_id: '#swagger-ui',
                deepLinking: true,
                presets: [
                    SwaggerUIBundle.presets.apis,
                    SwaggerUIStandalonePreset
                ],
                plugins: [
                    SwaggerUIBundle.plugins.DownloadUrl
                ],
                layout: "StandaloneLayout"
            }

            for (const attr in customOptions) {
                swaggerOptions[attr] = customOptions[attr]
            }

            const ui = SwaggerUIBundle(swaggerOptions);

            if (customOptions.oauth) {
                ui.initOAuth(customOptions.oauth)
            }

            if (customOptions.authAction) {
                ui.authActions.authorize(customOptions.authAction)
            }

            window.ui = ui;
        };
    """
end

function build_html_string(options::Options, js_string::String)::String
    favicon = options.custom_favicon == "" ? DEFAULT_FAVICON : "<link rel='icon' href=$(options.custom_favicon) />"
    title = options.custom_site_title
    style = options.custom_css
    stylesheet = options.custom_css_url == "" ? "" : "<link rel='stylesheet' type='text/css' href=$(options.custom_css_url) />"
    script = options.custom_js == "" ? "" : ""
    explorer = options.show_explorer ? "" : ".swagger-ui .topbar .download-url-wrapper { display: none; }"
    return """

        <!DOCTYPE html>

            <meta charset="UTF-8">
            <title>$(title)</title>
            <link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
            $(favicon)
            $(script)

            $(stylesheet)

    """
end


text:
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------

"""
    Dehn1899()

Max Dehns' triangulation proved in 1899.

The algorithm is described in the first chapter of Devadoss & Rourke 2011,
and is based on a theorem derived in 1899 by the German mathematician Max Dehn.
See https://en.wikipedia.org/wiki/Two_ears_theorem.

Because the algorithm relies on recursion, it is mostly appropriate for polygons
with small number of vertices. Currently, the implementation does not support holes.

## References

* Devadoss, S & Rourke, J. 2011. [Discrete and computational geometry]
  (https://press.princeton.edu/books/hardcover/9780691145532/discrete-and-computational-geometry)
"""
struct Dehn1899 <: DiscretizationMethod end

function discretize(𝒫::Chain, ::Dehn1899)
  # points on resulting mesh
  points = collect(vertices(𝒫))

  # Dehn's recursion
  connec = dehn1899(points, 1:length(points))

  SimpleMesh(points, connec)
end

function dehn1899(v::AbstractVector{Point{Dim,T}}, inds) where {Dim,T}
  I = CircularVector(inds)
  n = length(I)

  if n > 3 # split chain
    # find lowerleft vertex
    i = first(sortperm(coordinates.(v[I])))

    # left/right chains
    linds = i-1:i+1
    rinds = i+1:i+n-1

    # check if candidate diagonal is valid
    Δ = Triangle(v[I[linds]])
    intriangle = findall(j -> v[I[j]] ∈ Δ, rinds[2:end-1])
    isdiag = signarea(Δ) > atol(T)^2 && isempty(intriangle)

    # adjust diagonal if necessary
    if !isdiag
      l  = Line(v[I[i-1]], v[I[i+1]])
      js = rinds[intriangle .+ 1]
      k  = argmax([evaluate(Euclidean(), l, v[I[j]]) for j in js])
      j  = js[k]
      linds = i:j
      rinds = j:i+n
    end

    # we adjust the circular indices and
    # use `inds` instead of `I` in the
    # recursion to avoid memory copies
    linds = [mod1(ind,n) for ind in linds]
    rinds = [mod1(ind,n) for ind in rinds]

    # perform recursion
    left  = dehn1899(v, inds[linds])
    right = dehn1899(v, inds[rinds])
    [left; right]
  else
    # return the triangle
    [connect(Tuple(inds), Triangle)]
  end
end


text:
function setPosition!(mechanism::Mechanism{T}, body::Body{T};x::AbstractVector{T} = SVector{3,T}(0, 0, 0),q::Quaternion{T} = Quaternion{T}()) where T
    for i = 1:mechanism.No
        body.x[i] = x
        body.q[i] = q
    end
end

function setPosition!(mechanism::Mechanism{T}, body1::Body{T}, body2::Body{T};
    p1::AbstractVector{T} = SVector{3,T}(0, 0, 0), p2::AbstractVector{T} = SVector{3,T}(0, 0, 0), Δx::AbstractVector{T} = SVector{3,T}(0, 0, 0),Δq::Quaternion{T} = Quaternion{T}()) where T

    q2 = body1.q[1] * Δq
    x2 = body1.x[1] + vrotate(SVector{3,T}(p1 + Δx), body1.q[1]) - vrotate(SVector{3,T}(p2), q2)

    setPosition!(mechanism, body2;x = x2,q = q2)
end

function setPosition!(mechanism::Mechanism{T}, body1::Origin{T}, body2::Body{T};
    p1::AbstractVector{T} = SVector{3,T}(0, 0, 0), p2::AbstractVector{T} = SVector{3,T}(0, 0, 0), Δx::AbstractVector{T} = SVector{3,T}(0, 0, 0),Δq::Quaternion{T} = Quaternion{T}()) where T

    q2 = Δq
    x2 = p1 + Δx - vrotate(SVector{3,T}(p2), q2)

    setPosition!(mechanism, body2;x = x2,q = q2)
end

# Assumes first order integrator
# TODO higher order integrator
function setVelocity!(mechanism::Mechanism{T}, body::Body{T};v::AbstractVector{T} = SVector{3,T}(0, 0, 0),ω::AbstractVector{T} = SVector{3,T}(0, 0, 0)) where T
    Δt = mechanism.Δt
    body.x[1] = body.x[2] - v * Δt
    body.q[1] = Δt/2 * (body.q[2] * Quaternion(sqrt(4 / Δt^2 - dot(ω, ω)), -SVector{3,T}(ω))) # this accounts for the non-unit-quaternion inverse (q2 * conj(ωbar))
    body.s0 = [v;ω]
    s0tos1!(body)
    return
end

# Assumes first order integrator
# TODO higher order integrator
function setVelocity!(mechanism::Mechanism{T}, body1::Body{T}, body2::Body{T};
    p1::AbstractVector{T} = SVector{3,T}(0, 0, 0), p2::AbstractVector{T} = SVector{3,T}(0, 0, 0), Δv::AbstractVector{T} = SVector{3,T}(0, 0, 0), Δω::AbstractVector{T} = SVector{3,T}(0, 0, 0)) where T

    Δt = mechanism.Δt

    v1 = getv1(body1, Δt)
    ω1 = getω1(body1, Δt)

    vp1 = v1 + cross(ω1,p1)
    ωp1 = ω1

    vp2 = vp1 + Δv
    ωp2 = ωp1 + Δω

    v2 = vp2 + cross(ωp2,-p2)
    ω2 = ωp2

    setVelocity!(mechanism, body2;v = v2,ω = ω2)
end

# Assumes first order integrator
# TODO higher order integrator
function setVelocity!(mechanism::Mechanism{T}, body1::Origin{T}, body2::Body{T};
    p1::AbstractVector{T} = SVector{3,T}(0, 0, 0), p2::AbstractVector{T} = SVector{3,T}(0, 0, 0), Δv::AbstractVector{T} = SVector{3,T}(0, 0, 0),Δω::AbstractVector{T} = SVector{3,T}(0, 0, 0)) where T

    vp2 = Δv
    ωp2 = Δω

    v2 = vp2 + cross(ωp2,-p2)
    ω2 = ωp2

    setVelocity!(mechanism, body2;v = v2,ω = ω2)
end

function setForce!(mechanism::Mechanism{T}, body::Body{T};F::AbstractVector{T} = SVector{3,T}(0, 0, 0),r::AbstractVector{T} = SVector{3,T}(0, 0, 0),τ::AbstractVector{T} = SVector{3,T}(0, 0, 0)) where T
    τ += torqueFromForce(F, r)
    setForce!(body, F, τ, mechanism.No)
end


text:
@testset "Code update" begin
    include("code_update.jl")
end

@spawn for i in 1:10
    sleep(5 * 60)
    # Periodically print during testing so that Travis doesn't kill the process
    println("Dear Travis, please spare this slow process a few more minutes of runtime ($i).")
    flush(STDOUT)
end

function ctree_size(tr::Trace)
    # tree_size, but first make sure that it wasn't an error
    @assert !isa(tr.value, Exception)
    tree_size(tr)
end

@traceable h(a; k=3) = 2
g(x::Int) = 10+h(5.0)+h(10)
@traceable f(x) = g(x+2)
@test ctree_size(@trace f(10)) == 4

TraceCalls.show_val(io::IO, ::MIME"text/plain", ::Float64) = write(io, "some_float")
TraceCalls.show_call(io::IO, ::MIME"text/plain", ::typeof(f), tr::Trace) =
    write(io, "f was called")
@trace f(10)

# Check if symbols are correctly handled in macros
@traceable bar(; x=2) = [x,x]
@traceable bar2(x) = [x,x]
map(:@elapsed, @trace(bar(; x=:y)))
map(:@elapsed, @trace(bar2(:y)))

# splatting
@traceable splat(args::Int...)::Int = sum(args)
t = @trace splat(1,2,3)
@test t[1]() == 6
@test t[1].args == (1,2,3)

# kwarg splatting
@traceable kwsplat(;kwargs...) = map(first, kwargs)
t = @trace kwsplat(x=1,y=2,z=3)
@test t[1]() == [:x, :y, :z]

include("incl.jl")
@test ctree_size(@trace "incl.jl" couch()) == 2

@test ctree_size(@trace Base.isnull get(Nullable(10))) == 2

# compare_past_trace
@traceable function foo(x)
    my_length(x) + bar(x)
end
@traceable my_length(x) = length(x)
@traceable bar(x) = 10

u = [10,20,30]
tr = @trace foo(u)
push!(u, 40)
@test 0.25 == mean([TraceCalls.iseql(tr.value)
                    for tr in collect(compare_past_trace(tr, filter_out_equal=false))])

# NoTraceable
using TraceCalls
@traceable foo(x) = x+2
@testset "NoTraceable" begin
    @test ctree_size(@trace foo(10)) == 2
    @test ctree_size(@trace (NoTraceable(),) foo(10)) == 1
end

# filtering
@traceable f1(x) = f2(x) + f3(x)
@traceable f2(x) = x-10
@traceable f3(x) = f4(x)+20
@traceable f4(x) = 2*x
@testset "Filtering" begin
    tr = @trace f1(5) + f4(10)
    @test ctree_size(filter_lineage(sub->sub.func==f3, tr)) == 4
    @test ctree_size(filter(sub->sub.func==f3, tr)) == 2
    @test ctree_size(filter_cutting(sub->sub.func!=f3, tr)) == 4
end

# generated functions
@testset "Generated functions" begin
    include("incl.jl")
    tr_mouse = @trace "incl.jl" generated_mouse("hey")
    tr_mouse2 = @trace generated_mouse generated_mouse("hey")
    @test TraceCalls.value(tr_mouse) == "hey DataType"
    @test ctree_size(tr_mouse) == ctree_size(tr_mouse2) == 2
end

# JuliaLang#23809
tr_missing = @trace "incl.jl" generated_missing("hey")
@test ctree_size(tr_missing) == 2


text:
function chirp_lin(f0,t1,f1,fs,phase)
	#
	# f0: frequency at t=0 (Hz)
	# f1: frequency at t=t1 (seconds)
	# fs: sampling frequency (Hz)
	# phase: phase at t=0 (degrees)
	#
	# variable frequency - linear
	# f(t) = f0 + b*t, where b = (f1-f0)/t1
	#
	# javier.cara@upm.es, 2016 - january

	nt = Int(t1*fs)
	t = (0:nt-1)*(1/fs)

	b = (f1-f0)/t1
	x = Array(Float64,1,nt)
	for k in 1:nt
		  x[k] = sin(2*pi*(f0*t[k] + b/2*t[k]^2) + phase/360*2*pi)
	end

	return x

end

# ***************************************************************
function chirp_lin_test()

	f0=0.
	f1=20.
	t1=50.
	fs=100.
	phase=90.

	nt = Int(t1*fs)
	t = (0:nt-1)*(1/fs)

	x = chirp_lin(f0,t1,f1,fs,phase)

	return x,t
end

# **************************************************************
function chirp_log(f0,t1,f1,fs,phase)
	#
	# f0: frequency at t=0 (Hz)
	# f1: frequency at t=t1 (seconds)
	# fs: sampling frequency (Hz)
	# phase: phase at t=0 (degrees)
	#
	# variable frequency - linear
	# f(t) = f0*b^t, where b = (f1/f0)(1/t1)
	#
	# javier.cara@upm.es, 2016 - january

	if f0 == 0
	# f0 can't be zero
		f0 = 1.0e-6
	end

	nt = Int(t1*fs)
	t = (0:nt-1)*(1/fs)

	b = (f1/f0)^(1/t1)
	x = Array(Float64,1,nt)
	for k in 1:nt
		  x[k] = sin(2*pi*f0*(b^t[k]-1)/log(b) + phase/360*2*pi)
	end

	return x

end

# ***************************************************************
function chirp_log_test()

	f0=0.
	f1=20.
	t1=50.
	fs=100.
	phase=90.

	nt = Int(t1*fs)
	t = (0:nt-1)*(1/fs)

	x = chirp_log(f0,t1,f1,fs,phase)

	return x,t
end


text:
using TestContexts
using Test

test_set("context") do
    @test_throws ErrorException tc.foo
    @test test_name() == "context"

    test_set("patterns") do
        @test test_name() == "context/patterns"
        test_patterns([".*/match"])
        try

            did_run_match = false
            test_case("match") do
                @test test_name() == "context/patterns/match"
                did_run_match = true
            end
            @test did_run_match

            did_run_mismatch = false
            test_case("mismatch") do
                @test test_name() == "context/patterns/mismatch"  # untested
                did_run_mismatch = true  # untested
            end
            @test !did_run_mismatch

        finally
            test_patterns([])
        end
    end

    test_set("properties") do
        test_set("with_shared_foo", :foo => SharedValue("foo")) do
            test_case("with_shared_bar", :bar => SharedValue("bar")) do
                @test tc.foo == "foo"
                @test tc.bar == "bar"
            end

            test_case("without_bar") do
                @test tc.foo == "foo"
                @test_throws KeyError tc.bar
            end
        end

        did_make_foo = false
        test_set("with_private_foo", :foo => PrivateValue(() -> begin
            @test !did_make_foo
            did_make_foo = true
            "foo"
        end)) do
            test_case("ignore_foo") do
            end
            @test !did_make_foo

            test_case("access_foo") do
                @test tc.foo == "foo"
                @test tc.foo == "foo"
            end
            @test did_make_foo
        end

        did_make_foo = false
        did_finalize_foo = false
        test_set(
            "with_private_finalized_foo",
            :foo => PrivateValue(
                () -> begin
                    @test !did_make_foo
                    did_make_foo = true
                    "foo"
                end,
                (foo) -> begin
                    @test !did_finalize_foo
                    did_finalize_foo = true
                end,
            ),
        ) do
            test_case("ignore_foo") do
            end
            @test !did_make_foo
            @test !did_finalize_foo

            test_case("access_foo") do
                @test tc.foo == "foo"
                @test tc.foo == "foo"
            end
            @test did_make_foo
            @test did_finalize_foo
        end
    end
end


text:
#******************************************************************************#
#                                                                              #
#                                                         :::      ::::::::    #
#    shell.jl                                           :+:      :+:    :+:    #
#                                                     +:+ +:+         +:+      #
#    By: mngomane <mngomane@student.42.fr>          +#+  +:+       +#+         #
#                                                 +#+#+#+#+#+   +#+            #
#    Created: 2015/02/12 08:38:20 by mngomane          #+#    #+#              #
#    Updated: 2015/02/12 08:38:20 by mngomane         ###   ########.fr        #
#                                                                              #
#******************************************************************************#

include("commands.jl")
include("shell_colors.jl")
include("tools.jl")

loop = true

while loop
	print(prompt_string())
	entry = readline(STDIN)
	if entry == ""
		loop = false
		println("")
	else
		entry = entry[1:end - 1]
	end
	entry = join(split(entry))
	if entry == "exit()"
		loop = false
	elseif entry == "start()"
		check_return()
	elseif entry != ""
		println(error_prompt())
	end
end

max_stars_repo_name: mngomane/projects

max_issues_repo_name: mngomane/projects

max_forks_repo_name: mngomane/projects


text:
module PlotLib

include("plotutils.jl")
include("structs.jl")

using Flux
using PlotlyJS
using Plots

export plot_train_and_test_data, plot_loss_and_accuracy, plot_features, plot_decision_boundary

title_font_size = 18
tick_font_size = 16

"""
	plot_train_and_test_data(train_loader, test_loader, "Train", "Test")

Returns a PlotlyJS subplot with one row and two columns visualizing the two provided datasets.
"""
function plot_train_and_test_data(train_loader::Flux.Data.DataLoader, test_loader::Flux.Data.DataLoader; train_title = "", test_title = "")
	# define common layout
	layout = Layout(
		width = 1000, height = 1000, autosize = false,
		plot_bgcolor = "rgba(0, 0, 0, 0)", paper_bgcolor = "rgba(0, 0, 0, 0)",
		xaxis = attr(
			showgrid = true, gridcolor = "#e2e2e2",
			ticks = "outside", zeroline = false,
			tickfont = attr(size = tick_font_size)),
		yaxis = attr(
			showgrid = true, gridcolor = "#e2e2e2",
			ticks = "outside", zeroline = false,
			tickfont = attr(size = tick_font_size)),
	)

	# create two independent plots
	p_train = PlotlyJS.plot(PlotlyJS.scatter(
		x = train_loader.data[1][1,:], y = train_loader.data[1][2,:], mode = "markers",
		marker_color = PlotUtils.map_bool_to_color(train_loader.data[2][1,:], "red", "blue"),
		showlegend = false
	), layout)
	p_test = PlotlyJS.plot(PlotlyJS.scatter(
		x = test_loader.data[1][1,:], y = test_loader.data[1][2,:], mode = "markers",
		marker_color = PlotUtils.map_bool_to_color(test_loader.data[2][1,:], "red", "blue"),
		showlegend = false, showgrid = true
	), layout)

	# adjust common layout with individual titles
	# does not work for some reason :/
	PlotlyJS.relayout!(p_train, title = attr(text = train_title, font = attr(size = title_font_size)))
	PlotlyJS.relayout!(p_test, title = attr(text = test_title, font = attr(size = title_font_size)))

	# combine plots into one
	p = [p_train p_test]
	PlotlyJS.relayout!(p, plot_bgcolor = "rgba(0, 0, 0, 0)", paper_bgcolor = "rgba(0, 0, 0, 0)")
	p
end

"""
	plot_loss_and_accuracy(loss, accuracy)

Returns a PlotlyJS line plot with the data of the provided loss and accuracy vectors.
"""
function plot_loss_and_accuracy(loss::Vector{Any}, accuracy::Vector{Any}; args...)
	args = Args(; args...)
	PlotlyJS.plot([
		PlotlyJS.scatter(y = loss, x = 1:args.epochs, mode = "lines", name = "loss"),
		PlotlyJS.scatter(y = accuracy, x = 1:args.epochs, mode = "lines", name = "accuracy")
		],
		Layout(
			title = attr(text = "Loss and Accuracy", font = attr(size = title_font_size)),
			width = 1000, height = 1000, autosize = false,
			xaxis = attr(
				showgrid = false,
				ticks = "outside",
				tickfont = attr(size = tick_font_size)),
			yaxis = attr(
				range = [0, 1], dtick = 0.1, showgrid = false,
				ticks = "outside",
				tickfont = attr(size = tick_font_size)),
			legend = attr(font = attr(size = tick_font_size)),
			automargin = false,
			margin = attr(l = 0, r = 0, b = 0, t = 0, pad = 0),
			plot_bgcolor = "rgba(0, 0, 0, 0)",
			paper_bgcolor = "rgba(0, 0, 0, 0)"
		)
	)
end

"""
	plot_features(z1, z2)

Returns a PlotlyJS line plot with the data of both features z1 and z2.
"""
function plot_features(z1::Vector{Float64}, z2::Vector{Float64}; args...)
	args = Args(; args...)
	PlotlyJS.plot([
		PlotlyJS.scatter(y = z1, x = 1:args.epochs, mode = "lines", name = "z1"),
		PlotlyJS.scatter(y = z2, x = 1:args.epochs, mode = "lines", name = "z2")
		],
		Layout(
			title = attr(text = "Features", font = attr(size = title_font_size)),
			width = 1000, height = 1000, autosize = false,
			xaxis = attr(
				ticks = "outside",
				tickfont = attr(size = tick_font_size)),
			yaxis = attr(
				ticks = "outside",
				tickfont = attr(size = tick_font_size)),
			legend = attr(font = attr(size = tick_font_size)),
			margin = attr(l = 0, r = 0, b = 0, t = 0, pad = 0),
			plot_bgcolor = "rgba(0, 0, 0, 0)",
			paper_bgcolor = "rgba(0, 0, 0, 0)"
		)
	)
end

"""
	plot_decision_boundary(train_loader, model; title = "SGD Δ0.5")

Returns a PlotlyJS contour plot of the provided dataset according to the specified model.
"""
function plot_decision_boundary(loader::Flux.DataLoader, model; title = "")
	# grid and range step size
	n = 100
	# determine limits of given data
	x_max = maximum(loader.data[1][1,:]) + .25
	y_max = maximum(loader.data[1][2,:]) + .25
	x_min = minimum(loader.data[1][1,:]) - .25
	y_min = minimum(loader.data[1][2,:]) - .25

	r_x = LinRange(x_min, x_max, n)
	r_y = LinRange(y_min, y_max, n)

	# create grid to be used for the contours
	d1 = collect(Iterators.flatten(vcat([fill(v, (n, 1)) for v in r_x])))
	d2 = collect(Iterators.flatten(vcat([reshape(r_y, 1, :) for _ in 1:n])))
	grid = hcat(d1, d2)

	# use model to predict decision boundary based on grid
	gr_pred = model(grid')
	gr_pred = reshape(gr_pred[1,:], (n, n))

	# map classes (Boolean) to integers to be used as colors
	cols = PlotUtils.map_bool_to_color(loader.data[2][1,:], "#FF0000", "#0000FF")
	opacity = 0.90

	PlotlyJS.plot([
		# data points
		PlotlyJS.scatter(
			x = loader.data[1][1,:], y = loader.data[1][2,:],
			mode = "markers", marker = attr(color = cols, line_width = 1),
			showlegend = false
		),
		# actual contours
		PlotlyJS.contour(
			x = r_x, y = r_y, z = gr_pred,
			contours_start = -10, contours_end = 10, contours_size = 1,
			contours_coloring = "heatmap", colorscale = PlotUtils.get_custom_rdbu_scale(opacity),
			colorbar = attr(thickness = 25, len = 0.9, y = 0.425),
			opacity = opacity, showlegend = false
		),
		# highlight decision boundary line
		PlotlyJS.contour(
			x = r_x, y = r_y, z = gr_pred,
			contours_start = 0, contours_end = 0, contours_size = 0,
			contours_coloring = "lines", colorscale = [[0, "black"], [1, "black"]],
			showscale = false, showlegend = false, line = attr(width = 3)
		)],
		Layout(
			title = attr(text = title, font = attr(size = title_font_size)),
			width = 1000, height = 1000, autosize = false,
			xaxis = attr(
				range = [x_min, x_max],
				zeroline = false, zerolinewidth = 1, zerolinecolor = "black",
				automargin = false, showgrid = false,
				tickfont = attr(size = tick_font_size)),
			yaxis = attr(
				range = [y_min, y_max],
				zeroline = false, zerolinewidth = 1, zerolinecolor = "black",
				automargin = false, showgrid = false,
				tickfont = attr(size = tick_font_size)),
			legend = attr(font = attr(size = tick_font_size)),
			margin = attr(l = 0, r = 0, b = 0, t = 0, pad = 0),
			plot_bgcolor = "rgba(0, 0, 0, 0)",
			paper_bgcolor = "rgba(0, 0, 0, 0)"
		),
		config = PlotConfig(
			scrollZoom = false
		)
	)
end

end


text:
export Titanic

"""
    Titanic(; as_df = true, dir = nothing)

The Titanic dataset, describing the survival of passengers on the Titanic ship.

# Arguments

$ARGUMENTS_SUPERVISED_TABLE

# Fields

$FIELDS_SUPERVISED_TABLE

# Methods

$METHODS_SUPERVISED_TABLE

# Examples

```julia-repl
julia> using MLDatasets: Titanic

julia> using DataFrames

julia> dataset = Titanic()
Titanic:
  metadata => Dict{String, Any} with 5 entries
  features => 891×11 DataFrame
  targets => 891×1 DataFrame
  dataframe => 891×12 DataFrame

julia> describe(dataset.dataframe)
12×7 DataFrame
 Row │ variable     mean      min                  median   max                          nmissing  eltype
     │ Symbol       Union…    Any                  Union…   Any                          Int64     Type
─────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1 │ PassengerId  446.0     1                    446.0    891                                 0  Int64
   2 │ Survived     0.383838  0                    0.0      1                                   0  Int64
   3 │ Pclass       2.30864   1                    3.0      3                                   0  Int64
   4 │ Name                   Abbing, Mr. Anthony           van Melkebeke, Mr. Philemon         0  String
   5 │ Sex                    female                        male                                0  String7
   6 │ Age          29.6991   0.42                 28.0     80.0                              177  Union{Missing, Float64}
   7 │ SibSp        0.523008  0                    0.0      8                                   0  Int64
   8 │ Parch        0.381594  0                    0.0      6                                   0  Int64
   9 │ Ticket                 110152                        WE/P 5735                           0  String31
  10 │ Fare         32.2042   0.0                  14.4542  512.329                             0  Float64
  11 │ Cabin                  A10                           T                                 687  Union{Missing, String15}
  12 │ Embarked               C                             S                                   2  Union{Missing, String1}
```
"""
struct Titanic <: SupervisedDataset
    metadata::Dict{String, Any}
    features
    targets
    dataframe
end

function Titanic(; as_df = true, dir = nothing)
    @assert dir === nothing "custom `dir` is not supported at the moment."
    path = joinpath(@__DIR__, "..", "..", "..", "data", "titanic.csv")
    df = read_csv(path)
    features = df[!, Not(:Survived)]
    targets = df[!, [:Survived]]

    metadata = Dict{String, Any}()
    metadata["path"] = path
    metadata["feature_names"] = names(features)
    metadata["target_names"] = names(targets)
    metadata["n_observations"] = size(df, 1)
    metadata["description"] = TITANIC_DESCR

    if !as_df
        features = df_to_matrix(features)
        targets = df_to_matrix(targets)
        df = nothing
    end

    return Titanic(metadata, features, targets, df)
end

const TITANIC_DESCR = """
The titanic and titanic2 data frames describe the survival status of individual passengers on the Titanic.

The titanic data frame does not contain information from the crew, but it does contain actual ages of half of the passengers.
The principal source for data about Titanic passengers is the Encyclopedia Titanica.
The datasets used here were begun by a variety of researchers.
One of the original sources is Eaton & Haas (1994)
Titanic: Triumph and Tragedy, Patrick Stephens Ltd, which includes a passenger list created by many researchers and edited by Michael A. Findlay.

The variables on our extracted dataset are pclass, survived, name, age, embarked, home.dest, room, ticket, boat, and sex.
pclass refers to passenger class (1st, 2nd, 3rd), and is a proxy for socio-economic class.
Age is in years, and some infants had fractional values.
The titanic2 data frame has no missing data and includes records for the crew, but age is dichotomized at adult vs. child.
These data were obtained from Robert Dawson, Saint Mary's University, E-mail.
The variables are pclass, age, sex, survived.
These data frames are useful for demonstrating many of the functions in Hmisc as well as
demonstrating binary logistic regression analysis using the Design library.
For more details and references see Simonoff, Jeffrey S (1997): The "unusual episode" and a second statistics course.
J Statistics Education, Vol. 5 No. 1. Thomas Cason of UVa has greatly updated and improved the titanic data frame
using the Encyclopedia Titanica and created a new dataset called titanic3.
These datasets reflects the state of data available as of 2 August 1999.
Some duplicate passengers have been dropped, many errors corrected, many missing ages filled in, and new variables created.

DATASET specs

NAME:	titanic3
TYPE:	Census
SIZE:	1309 Passengers, 14 Variables

DESCRIPTIVE ABSTRACT:

The titanic3 data frame describes the survival status of individual passengers on the Titanic.
The titanic3 data frame does not contain information for the crew, but it does contain actual and estimated ages for almost 80% of the passengers.

SOURCES:

Hind, Philip. Encyclopedia Titanica. Online-only resource. Retrieved 01Feb2012 from http://www.encyclopedia-titanica.org/

VARIABLE DESCRIPTIONS

Pclass	Passenger Class (1 = 1st; 2 = 2nd; 3 = 3rd)
survival	Survival (0 = No; 1 = Yes)
name	Name
sex	Sex
age	Age
sibsp	Number of Siblings/Spouses Aboard
parch	Number of Parents/Children Aboard
ticket	Ticket Number
fare	Passenger Fare (British pound)
cabin	Cabin
embarked	Port of Embarkation (C = Cherbourg; Q = Queenstown; S = Southampton)
boat	Lifeboat
body	Body Identification Number
home.dest	Home/Destination

SPECIAL NOTES

Pclass is a proxy for socio-economic status (SES) 1st ~ Upper; 2nd ~ Middle; 3rd ~ Lower

Age is in Years; Fractional if Age less than One (1) If the Age is estimated, it is in the form xx.5

Fare is in Pre-1970 British Pounds ()
Conversion Factors: 1 = 12s = 240d and 1s = 20d

With respect to the family relation variables (i.e. sibsp and parch) some relations were ignored.
The following are the definitions used for sibsp and parch.

Sibling:	Brother, Sister, Stepbrother, or Stepsister of Passenger Aboard Titanic
Spouse:	Husband or Wife of Passenger Aboard Titanic (Mistresses and Fiances Ignored)
Parent:	Mother or Father of Passenger Aboard Titanic
Child:	Son, Daughter, Stepson, or Stepdaughter of Passenger Aboard Titanic

Other family relatives excluded from this study include cousins, nephews/nieces, aunts/uncles, and in-laws.
Some children travelled only with a nanny, therefore parch=0 for them.
    As well, some travelled with very close friends or neighbors in a village, however, the definitions do not support such relations.

An interesting result may be obtained using functions from the Hmisc library.

attach	(titanic3)
plsmo	(age, survived, group=sex, datadensity=T)
# or group=pclass plot	(naclus	(titanic3)) # study patterns of missing values summary	(survived ~ age + sex + pclass + sibsp + parch, data=titanic3)
"""

function Base.getproperty(::Type{Titanic}, s::Symbol)
    if s == :features
        @warn "Titanic.features() is deprecated, use `Titanic().features` instead."
        return () -> Titanic(as_df=false).features
    elseif s == :targets
        @warn "Titanic.targets() is deprecated, use `Titanic().targets` instead."
        return () -> Titanic(as_df=false).targets
    elseif s == :feature_names
        @warn "Titanic.feature_names() is deprecated, use `Titanic().feature_names` instead."
        return () -> Titanic().metadata["feature_names"]
    else
        return getfield(Titanic, s)
    end
end


text:
module TWOPLAYER
export GameEnv, GameSpec
include("game.jl")
end


text:
using SequentialMonteCarlo
import SequentialMonteCarlo.eta
using RNGPool
import SMCExamples.StochVolatility.defaultSVModel
using Test
import Statistics: std, mean

setRNGs(0)

N = 32768
n = 10
numTrials = 5
nt = Threads.nthreads()
model, guidedmodel, theta, ys = defaultSVModel(n)

function estimate_mean(; guided=false, filtering=false)
    m = guided ? guidedmodel : model
    smcio = SMCIO{m.particle, m.pScratch}(N, n, nt, false)
    smc!(m, smcio)
    return eta(smcio, particle -> particle.x, filtering, n)
end

guided_predictive_means = [estimate_mean(guided=true, filtering=false) for _ in 1:numTrials]
guided_filtering_means  = [estimate_mean(guided=true, filtering=true) for _ in 1:numTrials]
predictive_means        = [estimate_mean(guided=false, filtering=false) for _ in 1:numTrials]
filtering_means         = [estimate_mean(guided=false, filtering=true) for _ in 1:numTrials]

@test mean(guided_filtering_means) ≈ mean(filtering_means) atol=0.05
@test std(guided_filtering_means) ≤ std(filtering_means)

@test mean(guided_predictive_means) ≈ mean(predictive_means) atol=0.05

smcio = SMCIO{model.particle, model.pScratch}(N, n, nt, false)
smc!(model, smcio)

smcio_guided = SMCIO{guidedmodel.particle, guidedmodel.pScratch}(N, n, nt, false)
smc!(guidedmodel, smcio_guided)

smcio.logZhats
smcio_guided.logZhats

@test smcio.logZhats ≈ smcio_guided.logZhats atol=0.05


text:
module BinaryProvider

using Libdl

# Utilities for controlling verbosity
include("LoggingUtils.jl")
# Include our subprocess running functionality
include("OutputCollector.jl")
# External utilities such as downloading/decompressing tarballs
include("PlatformEngines.jl")
# Platform naming
include("PlatformNames.jl")
# Everything related to file/path management
include("Prefix.jl")
# Abstraction of "needing" a file, that would trigger an install
include("Products.jl")

# Compat shims
include("CompatShims.jl")

function __init__()
    global global_prefix

    # Initialize our global_prefix
    global_prefix = Prefix(joinpath(dirname(pathof(@__MODULE__)), "..", "global_prefix"))

    # Find the right download/compression engines for this platform
    probe_platform_engines!()
end

# gotta go fast
include("precompile.jl")
_precompile_()

end # module


text:
# MetidaCu
# Copyright © 2019-2020 Vladimir Arnautov aka PharmCat <mail@pharmcat.net>
using Metida
using MetidaCu
using Test, CSV, DataFrames, StatsModels, CategoricalArrays

df0 = CSV.File(joinpath(dirname(pathof(Metida)),"..","test","csv","df0.csv"); types = [String, String, String, String, Float64, Float64]) |> DataFrame
transform!(df0, :subject => categorical, renamecols=false)
transform!(df0, :period => categorical, renamecols=false)
transform!(df0, :sequence => categorical, renamecols=false)
transform!(df0, :formulation=> categorical, renamecols=false)
@testset "  Basic test                                               " begin
    lmm = LMM(@formula(var~sequence+period+formulation), df0;
    random = VarEffect(@covstr(formulation|subject), CSH),
    repeated = VarEffect(@covstr(formulation|subject), Metida.DIAG),
    )
    fit!(lmm; solver = :cuda, rholinkf = :sigm, f_tol=1e-11, x_tol=1e-11)
    #10.065239006121315
    #10.065759784473597
    #10.06534259559994
    @test lmm.result.reml       ≈ 10.065238620495808 atol=1E-3
end