text:
## For generating a sysimage with ObjectDetector built-in, to make loading faster
# Make sure to have an un-modified sysimage. i.e. re-download julia

# Step 1: Add PackageCompilerX and activate the folder this file sits in
# Step 2: Make sure ObjectDetector loads
# Step 3: Run
# Note: You will likely see Zygote-related precompile failures

using PackageCompilerX
create_sysimage(:ObjectDetector, sysimage_path=joinpath(@__DIR__, "ObjectDetector.so"),
        precompile_execution_file = joinpath(@__DIR__, "precompile.jl"))

# Step 4: Launch julia pointing to this new sysimage
# i.e. run this in bash:
#==
cd /path/to/ObjectDetector.jl/dev/compilation
julia-1.3 -q -JObjectDetector.so
==#
#(~5 seconds to loaded REPL with ObjectDetector loaded)
#==
julia> @time ObjectDetector.YOLO.v3_608_COCO(silent=false)
4.096615 seconds (4.74 M allocations: 2.239 GiB, 12.35% gc time)
==#


text:
function _curr_branch(repodir)
    !_check_gitdir(repodir) && return ""
    out = _run("git -C $(repodir) rev-parse --abbrev-ref HEAD 2>&1"; verbose = false, ignorestatus = true)
    return string(strip(out))
end

ext: jl


text:
"""
    NDIndex(i, j, k...)   -> I
    NDIndex((i, j, k...)) -> I

A multidimensional index that refers to a single element. Each dimension is represented by
a single `Int` or `StaticInt`.

```julia
julia> using Static

julia> i = NDIndex(static(1), 2, static(3))
NDIndex(static(1), 2, static(3))

julia> i[static(1)]
static(1)

julia> i[1]
1

```
"""
struct NDIndex{N,I<:Tuple{Vararg{Union{StaticInt,Int},N}}} <: AbstractCartesianIndex{N}
    index::I

    NDIndex{N}(i::Tuple{Vararg{Union{StaticInt,Int},N}}) where {N} = new{N,typeof(i)}(i)
    NDIndex{N}(index::Tuple) where {N} = _ndindex(static(N), _flatten(index...))
    NDIndex{N}(index...) where {N} = NDIndex{N}(index)

    NDIndex{0}(::Tuple{}) = new{0,Tuple{}}(())
    NDIndex{0}() = NDIndex{0}(())

    NDIndex(i::Tuple{Vararg{Union{StaticInt,Int},N}}) where {N} = new{N,typeof(i)}(i)
    NDIndex(i::Vararg{Union{StaticInt,Int},N}) where {N} = NDIndex(i)

    NDIndex(index::Tuple) = NDIndex(_flatten(index...))
    NDIndex(index...) = NDIndex(index)
end

_ndindex(n::StaticInt{N}, i::Tuple{Vararg{Union{Int,StaticInt},N}}) where {N} = NDIndex(i)
function _ndindex(n::StaticInt{N}, i::Tuple{Vararg{Any,M}}) where {N,M}
    M > N && throw(ArgumentError("input tuple of length $M, requested $N"))
    return NDIndex(_fill_to_length(i, n))
end
_fill_to_length(x::Tuple{Vararg{Any,N}}, n::StaticInt{N}) where {N} = x
@inline function _fill_to_length(x::Tuple{Vararg{Any,M}}, n::StaticInt{N}) where {M,N}
    return _fill_to_length((x..., static(1)), n)
end

_flatten(i::StaticInt{N}) where {N} = (i,)
_flatten(i::Integer) = (Int(i),)
_flatten(i::Base.AbstractCartesianIndex) = _flatten(Tuple(i)...)
@inline _flatten(i::StaticInt, I...) = (i, _flatten(I...)...)
@inline _flatten(i::Integer, I...) = (Int(i), _flatten(I...)...)
@inline function _flatten(i::Base.AbstractCartesianIndex, I...)
    return (_flatten(Tuple(i)...)..., _flatten(I...)...)
 end
Base.Tuple(index::NDIndex) = index.index

Base.show(io::IO, i::NDIndex) = (print(io, "NDIndex"); show(io, Tuple(i)))

# length
Base.length(::NDIndex{N}) where {N} = N
Base.length(::Type{NDIndex{N,I}}) where {N,I} = N

# indexing
@propagate_inbounds function Base.getindex(x::NDIndex{N,T}, i::Int)::Int where {N,T}
    return Int(getfield(Tuple(x), i))
end
@propagate_inbounds function Base.getindex(x::NDIndex{N,T}, i::StaticInt{I}) where {N,T,I}
    return getfield(Tuple(x), I)
end

# Base.get(A::AbstractArray, I::CartesianIndex, default) = get(A, I.I, default)
# eltype(::Type{T}) where {T<:CartesianIndex} = eltype(fieldtype(T, :I))

Base.setindex(x::NDIndex, i, j) = NDIndex(Base.setindex(Tuple(x), i, j))

# equality
Base.:(==)(x::NDIndex{N}, y::NDIndex{N}) where N = Tuple(x) == Tuple(y)

# zeros and ones
Base.zero(::NDIndex{N}) where {N} = zero(NDIndex{N})
Base.zero(::Type{NDIndex{N}}) where {N} = NDIndex(ntuple(_ -> static(0), Val(N)))
Base.oneunit(::NDIndex{N}) where {N} = oneunit(NDIndex{N})
Base.oneunit(::Type{NDIndex{N}}) where {N} = NDIndex(ntuple(_ -> static(1), Val(N)))

@inline function Base.IteratorsMD.split(i::NDIndex, V::Val)
    i, j = Base.IteratorsMD.split(Tuple(i), V)
    return NDIndex(i), NDIndex(j)
end

# arithmetic, min/max
@inline Base.:(-)(i::NDIndex{N}) where {N} = NDIndex{N}(map(-, Tuple(i)))
@inline function Base.:(+)(i1::NDIndex{N}, i2::NDIndex{N}) where {N}
    return NDIndex(map(+, Tuple(i1), Tuple(i2)))
end
@inline function Base.:(-)(i1::NDIndex{N}, i2::NDIndex{N}) where {N}
    return NDIndex(map(-, Tuple(i1), Tuple(i2)))
end
@inline function Base.min(i1::NDIndex{N}, i2::NDIndex{N}) where {N}
    return NDIndex(map(min, Tuple(i1), Tuple(i2)))
end
@inline function Base.max(i1::NDIndex{N}, i2::NDIndex{N}) where {N}
    return NDIndex(map(max, Tuple(i1), Tuple(i2)))
end
@inline Base.:(*)(a::Integer, i::NDIndex{N}) where {N} = NDIndex(map(x->a*x, Tuple(i)))
@inline Base.:(*)(i::NDIndex, a::Integer) = *(a, i)

Base.CartesianIndex(x::NDIndex) = dynamic(x)

# comparison
@inline function Base.isless(x::NDIndex{N}, y::NDIndex{N}) where {N}
    return Bool(_isless(static(0), Tuple(x), Tuple(y)))
end

lt(x::NDIndex{N}, y::NDIndex{N}) where {N} = _isless(static(0), Tuple(x), Tuple(y))

_final_isless(c::Int) = c === 1
_final_isless(::StaticInt{N}) where {N} = static(false)
_final_isless(::StaticInt{1}) = static(true)
_isless(c::C, x::Tuple{}, y::Tuple{}) where {C} = _final_isless(c)
function _isless(c::C, x::Tuple, y::Tuple) where {C}
    return _isless(icmp(c, x, y), Base.front(x), Base.front(y))
end
icmp(::StaticInt{0}, x::Tuple, y::Tuple) = icmp(last(x), last(y))
icmp(::StaticInt{N}, x::Tuple, y::Tuple) where {N} = static(N)
function icmp(cmp::Int, x::Tuple, y::Tuple)
    if cmp === 0
        return icmp(Int(last(x)), Int(last(y)))
    else
        return cmp
    end
end
icmp(a, b) = _icmp(lt(a, b), a, b)
_icmp(x::StaticBool, a, b) = ifelse(x, static(1), __icmp(eq(a, b)))
_icmp(x::Bool, a, b) = ifelse(x, 1, __icmp(a == b))
__icmp(x::StaticBool) = ifelse(x, static(0), static(-1))
__icmp(x::Bool) = ifelse(x, 0, -1)

#  Necessary for compatibility with Base
# In simple cases, we know that we don't need to use axes(A). Optimize those
# until Julia gets smart enough to elide the call on its own:
@inline function Base.to_indices(A, inds, I::Tuple{NDIndex, Vararg{Any}})
    return to_indices(A, inds, (Tuple(I[1])..., Base.tail(I)...))
end
# But for arrays of CartesianIndex, we just skip the appropriate number of inds
@inline function Base.to_indices(A, inds, I::Tuple{AbstractArray{NDIndex{N}}, Vararg{Any}}) where N
    _, indstail = Base.IteratorsMD.split(inds, Val(N))
    return (to_index(A, I[1]), to_indices(A, indstail, Base.tail(I))...)
end


text:
module TopicModels

import Base.length

typealias RaggedMatrix{T} Array{Array{T,1},1}

type Corpus
  documents::RaggedMatrix{Int64}
  weights::RaggedMatrix{Float64}

  Corpus(documents::RaggedMatrix{Int64},
         weights::RaggedMatrix{Float64}) = begin
    return new(
      documents,
      weights
    )
  end

  Corpus(documents::RaggedMatrix{Int64}) = begin
    weights = map(documents) do doc
      ones(Float64, length(doc))
    end
    return new(
      documents,
      weights
    )
  end
end

type Model
  alphaPrior::Vector{Float64}
  betaPrior::Float64
  topics::Array{Float64,2}
  topicSums::Vector{Float64}
  documentSums::Array{Float64,2}
  assignments::RaggedMatrix{Int64}
  frozen::Bool
  corpus::Corpus

  Model(alphaPrior::Vector{Float64},
        betaPrior::Float64,
        V::Int64,
        corpus::Corpus) = begin
    K = length(alphaPrior)
    m = new(
      alphaPrior,
      betaPrior,
      zeros(Float64, K, V), # topics
      zeros(Float64, K), # topicSums
      zeros(Float64, K, length(corpus.documents)), #documentSums
      fill(Array(Int64, 0), length(corpus.documents)), # assignments
      false,
      corpus
    )
    initializeAssignments(m)
    return m
  end

  Model(trainedModel::Model, corpus::Corpus) = begin
    m = new(
      trainedModel.alphaPrior,
      trainedModel.betaPrior,
      trainedModel.topics,
      trainedModel.topicSums,
      trainedModel.documentSums,
      fill(Array(Int64, 0), length(corpus.documents)),
      true,
      corpus
    )
    initializeAssignments(m)
    return m
  end
end

function length(corpus::Corpus)
  return length(corpus.documents)
end

function initializeAssignments(model::Model)
  for dd in 1:length(model.corpus)
    @inbounds words = model.corpus.documents[dd]
    @inbounds model.assignments[dd] = fill(0, length(words))
    for ww in 1:length(words)
      @inbounds word = words[ww]
      topic = sampleMultinomial(model.alphaPrior)
      @inbounds model.assignments[dd][ww] = topic
      updateSufficientStatistics(
        word, topic, dd, model.corpus.weights[dd][ww], model)
    end
  end
  return
end

function sampleMultinomial(p::Array{Float64,1})
  pSum = sum(p)
  r = rand() * pSum
  K = length(p)
  for k in 1:K
    if r < p[k]
      return k
    else
      r -= p[k]
    end
  end
  return 0
end

function wordDistribution(word::Int,
                          document::Int,
                          model::Model,
                          out::Vector{Float64})
  V = size(model.topics, 2)
  for ii in 1:length(out)
    u = (model.documentSums[ii, document] + model.alphaPrior[ii]) *
        (model.topics[ii, word] + model.betaPrior) /
        (model.topicSums[ii] + V * model.betaPrior)
    @inbounds out[ii] = u
  end
  return
end

function sampleWord(word::Int,
                    document::Int,
                    model::Model,
                    p::Vector{Float64})
  wordDistribution(word, document, model, p)
  sampleMultinomial(p)
end

function updateSufficientStatistics(word::Int64,
                                    topic::Int64,
                                    document::Int64,
                                    scale::Float64,
                                    model::Model)
  fr = Float64(!model.frozen)
  @inbounds model.documentSums[topic, document] += scale
  @inbounds model.topicSums[topic] += scale * fr
  @inbounds model.topics[topic, word] += scale * fr
  return
end

function sampleDocument(document::Int,
                        model::Model)
  @inbounds words = model.corpus.documents[document]
  Nw = length(words)
  @inbounds weights = model.corpus.weights[document]
  K = length(model.alphaPrior)
  p = Array(Float64, K)
  @inbounds assignments = model.assignments[document]
  for ii in 1:Nw
    @inbounds word = words[ii]
    @inbounds oldTopic = assignments[ii]
    updateSufficientStatistics(word, oldTopic, document, -weights[ii], model)
    newTopic = sampleWord(word, document, model, p)
    @inbounds assignments[ii] = newTopic
    updateSufficientStatistics(word, newTopic, document, weights[ii], model)
  end
  return
end

function sampleCorpus(model::Model)
  for ii in 1:length(model.corpus)
    sampleDocument(ii, model)
  end
  return
end

# Note, files are zero indexed, but we are 1-indexed.
function termToWordSequence(term::AbstractString)
  parts = split(term, ":")
  fill(parse(Int64, parts[1]) + 1, parse(Int64, parts[2]))
end

# The functions below are designed for public consumption
function trainModel(model::Model,
                    numIterations::Int64)
  for ii in 1:numIterations
    println(string("Iteration ", ii, "..."))
    sampleCorpus(model)
  end
  return
end

function topTopicWords(model::Model,
                       lexicon::Array{ASCIIString,1},
                       numWords::Int64)
  [lexicon[reverse(sortperm(model.topics'[1:end, row]))[1:numWords]]
   for row in 1:size(model.topics,1)]
end

function readDocuments(stream)
    lines = readlines(stream)
    convert(RaggedMatrix{Int64},
            [vcat([termToWordSequence(term) for term in split(line, " ")[2:end]]...)
             for line in lines])
end

function readLexicon(stream)
  lines = readlines(stream)
  map(chomp, convert(Array{AbstractString,1}, lines))
end

export Corpus,
       Model,
       readDocuments,
       readLexicon,
       topTopicWords,
       trainModel
end


text:
using ActiveSetMethods
using PowerModels, JuMP, GLPK

PowerModels.silence()

build_acp(data_file::String) = instantiate_model(
    PowerModels.parse_file(data_file),
    ACPPowerModel,
    PowerModels.build_opf
)

function run_opf(data_file::String, max_iter::Int = 100, algorithm = "Line Search")
    pm = build_acp(data_file)
    result = optimize_model!(pm, optimizer = optimizer_with_attributes(
        ActiveSetMethods.Optimizer,
        "OutputFlag" => 0,
        "external_optimizer" => GLPK.Optimizer,
        "max_iter" => max_iter,
        "algorithm" => algorithm,
    ))
    return result
end

max_stars_repo_name: exanauts/ActiveSetMethods

max_issues_repo_name: exanauts/ActiveSetMethods

max_forks_repo_name: exanauts/ActiveSetMethods


text:
module CreateTableTodos

using Genie, SearchLight

function up()
  SearchLight.query("""CREATE SEQUENCE todos__seq_id""")
  SearchLight.query("""
    CREATE TABLE IF NOT EXISTS todos (
      id            integer CONSTRAINT todos__idx_id PRIMARY KEY DEFAULT NEXTVAL('todos__seq_id'),
      title         varchar(500) NOT NULL,
      completed     boolean DEFAULT FALSE,
      created_at    timestamp,
      updated_at    timestamp DEFAULT current_timestamp
    )
  """)
  SearchLight.query("""ALTER SEQUENCE todos__seq_id OWNED BY todos.id""")
end

function down()
  SearchLight.query("DROP TABLE todos")
end

end

max_stars_repo_name: essenciary/genie-todo-mvc

max_issues_repo_name: essenciary/genie-todo-mvc

max_forks_repo_name: essenciary/genie-todo-mvc


text:
module MultithreadingBenchmarks

"""
    MultithreadingBenchmarks.measure_work(f)
The main interface for the code to be benchmarked: provide a work function, `f(i,v,n)` which
will be called repeatedly in a loop based on the provided NUM_QUERIES and QUERY_SIZE
environment variables.
"""
function measure_work end

include("bench_harness.jl")
include("common.jl")

end # module


text:
module JCheck

include("generate.jl")

export generate
export specialcases

export SquareMatrix

include("Quickcheck.jl")

export Quickcheck

export @add_predicate
export @quickcheck

include("FailedTests.jl")

export load

export @getcases

include("shrink.jl")

export shrink
export shrinkable

end


text:
# Lattice math utils implementation in Julia
# Copyright (C): Jaka Smrekar (vinctux) <vinctux@outlook.com>, 2016
#
# References:      [1]  https://eprint.iacr.org/2014/725.pdf
#                           Ruan de Clercq et al., 2014
#                           Efficient Software Implementation of Ring-LWE Encryption
#                  [2]  https://eprint.iacr.org/2015/138.pdf
#                           Vikram Singh, 2015
#                           A Practical Key Exchange for the Internet using Lattice Cryptography
#                  [3]  https://eprint.iacr.org/2016/049.pdf
#                           Christoph M. Mayer, 2016
#                           Implementing a Toolkit for Ring-LWE Based Cryptography
#                                            in Arbitrary Cyclotomic Number Fields
#                  [4]  https://securewww.esat.kuleuven.be/cosic/publications/article-2444.pdf
#                           Sujoy Sinha Roy et al., 2014
#                           Compact Ring-LWE Cryptoprocessor
#                  [5]  https://www.microsoft.com/en-us/research/wp-content/uploads/2016/05/RLWE-1.pdf
#                           Patrick Longa and Michael Naehrig, 2016
#                           Speeding up the Number Theoretic Transform
#                           for Faster Ideal Lattice-Based Cryptography
#                  [6]  http://web.maths.unsw.edu.au/~davidharvey/papers/fastntt/
#                           David Harvey, 2013
#                           Faster arithmetic for number-theoretic transforms
#                  [7]  https://www.math.auckland.ac.nz/~sgal018/gen-gaussians.pdf
#                           Nagarjun C. Dwarakanath and Steven D. Galbraith, 2014
#                           Sampling from Discrete Gaussians for Lattice-based
#                                         Cryptography on a constrained Device
# x86 C reference: [C1] https://github.com/ruandc/Ring-LWE-Encryption/blob/master/x86
#                  [C2] https://github.com/dconnolly/msr-latticecrypto/blob/master/generic/ntt.c
#                  [C3] https://github.com/open-quantum-safe/liboqs/tree/master/src/kex_rlwe_bcns15

using Krypto

abstract Moduli
type LatticeModuli <: Moduli
    k::Int8
    m::Int8
    l::Int8
end
Int16(x::LatticeModuli) = Int16(x.k * 2^x.m + x.l)
Int(x::LatticeModuli) = Int16(x)

# K-RED reduction function [5:p7]
function KRED(C::Integer, Q::LatticeModuli)
    M = 2^Q.m
    C0 = C % M
    C1 = div(C, M)
    return Q.k * C0 - C1
end

# K-RED-2X reduction function [5:p7]
function KRED2(C::Integer, Q::LatticeModuli)
    M = 2^Q.m
    C0 = C % M
    C1 = div(C, M) % M
    C2 = div(C, M << Q.m)
    return Q.k * C0 - C1 + C2
end

# Optimized Forward NTT-CT with K-RED reduction [5:p9]
# FIXME: NTTK currently not working. It's trying to access A @ 1537, bound is 1025,
#        although it should be 1024.
function NTTK(A::Array{Int16, 1}, Q::LatticeModuli, n::Integer)
    k, N = n, 1
    for m in vcat([1], [N <<= 1 for _ in 1:(ndigits(n, 2) - 2)])
        k >>= 1
        for i in 0:m
            jx = 2 * i * k + 1
            S = Ψ[n][m + i]
            for j in jx:(jx + k - 1)
                U = A[j]
                V = A[j + k] * S
                if m == 128
                    U = KRED(U, Q)
                    V = KRED2(V, Q)
                else
                    V = KRED(V, Q)
                end
                A[j] = U + V
                A[j + k] = U - V
            end
        end
    end
    return A
end

# Optimized INTT-GS with K-RED reduction [5:p10]
function INTTK(A::Array{Int16, 1}, Q::LatticeModuli, n::Integer)
    k, N = 1, n << 1
    for m in [N >>= 1 for _ in 1:(ndigits(N, 2) - 2)]
        j1 = 2
        h = m >> 1
        for i in 0:h
            j2 = j1 + k - 1
            S = Ψ_[n][h + i]
            for j in j1:j2
                U = A[j]
                V = A[j + k]
                if m == 32
                    A[j] = KRED(a[j], Q)
                    A[j + k] = KRED2(a[j + k], Q)
                else
                    A[j + k] = KRED(a[j + k], Q)
                end
            end
            j1 += 2k
        end
        k <<= 1
    end
    for j in 1:(k + 1)
        U = A[j]
        V = A[j + k]
        A[j] = KRED((U + V) * rev(rev(n) * rev(k^11)), Q)
        A[j + k] = KRED((U - V) * rev(rev(n) * rev(k^10) * Ψ_[n][1]), Q)
    end
    return A
end

# Plain NTT-CT from [C1]
function NTT(A::Array{Int16, 1}, Q::LatticeModuli, n::Integer)
    i, q, N = 0, Int16(Q), 1
    for m in [N <<= 1 for _ in 1:(ndigits(n, 2) - 2)]
        ξ, ω = Ω[i += 1], Ω[i += 1]
        for j in 1:2:m
            for k in 0:2m:n
                u1 = A[j + k]
                t1 = (ω * A[j + k + 1]) % q

                u2 = A[j + k + m]
                t2 = (ω * A[j + k + m + 1]) % q

                A[j + k] = (u1 + t1) % q
                A[j + k + 1] = (u2 + t2) % q

                A[j + k + m] = (u1 - t1) % q
                A[j + k + m + 1] = (u2 - t2) % q
            end
            ω = ω * ξ % Int16(Q)
        end
    end

    ξ = 5118
    ω = 1065
    for j in 0:(div(n, 2) - 1)
        t1 = (ω * A[2 * j + 2]) % q
        u1 = A[2 * j + 1];
        A[2 * j + 1] = (u1 + t1) % q
        A[2 * j + 2] = (u1 - t1) % q
        ω = (ω * ξ) % q
    end
    return A
end

# Uniformly sample from [-B:B] a polynomial in ring
# FIXME: This should be Knuth-Yao.
function UniformSample(B::Int16, N::Integer)
    B < 0 && error("Bound limit cannot be negative.")
    E = Array{Int16, 1}()
    for i in 1:N append!(E, randbit(B)) end
    return E
end

# Element-wise multiplication of polynomials, in ring ZZ/Q
function *(x::Array{Int16, 1}, y::Array{Int16, 1}, Q::LatticeModuli)
    l = length(x)
    assert(l == length(y))
    return [(x[i] * y[i]) % Int16(Q) for i in 1:l]
end

# Element-wise addtion of polynomials, in ring ZZ/Q
function +(x::Array{Int16, 1}, y::Array{Int16, 1}, Q::LatticeModuli)
    l = length(x)
    assert(l == length(y))
    return [(x[i] + y[i]) % Int16(Q) for i in 1:l]
end

# Generate a CS-random polynomial of length L in ring ZZ/Q
function genrandpoly{T<:Integer}(L::T, Q::LatticeModuli; ntt_::Bool = false, N::Integer = 1024)
    A, R = Array{Int16, 1}(), RandomDevice()
    for i in 1:L append!(A, rand(R, Int16) % Int16(Q)) end
    return ntt_ ? NTTK(A, Q, N) : A
end


text:
# Example that performes a NonLinear 2-D Wavelet Approximation
# via thresholding

#push path
push!(LOAD_PATH,pwd()*"/src") # for julia 0.4 you need to put your path
#import libraries
using FWT
using PyPlot
using Images

n = 1024;
name = "data_samples/ernst_reuter_haus.bmp";
f = load_image(name, n);
f = rescale(sum(f,3));
f = f[:,:,1];

Jmax = round(Int64, n/eta);
Jmin = 1;

# Display the threshold coefficients

clf;
subplot(1,2,1);
plot_wavelet(fW,Jmin);
title("Original coefficients");
subplot(1,2,2);
plot_wavelet(fWT,Jmin);
title("Thresholded coefficients");

# number of kept coefficients
m = round(n^2/16);
# compute the threshold T
Jmin = 1;
fW = FWT.perform_wavortho_transf(f,Jmin,+1, h);
# select threshold
v = sort(abs(fW[:]));
if v[1]<v[n^2]
    v = FWT.reverse(v);
end
# inverse transform
T = v[round(Int64,m)];
fWT = fW .* (abs(fW).>T);
# inverse
fnlin = FWT.perform_wavortho_transf(fWT,Jmin,-1, h);
# display
clf;
u1 = @sprintf("Linear, SNR=%.3fdB", snr(f,fLin));
u2 = @sprintf("Non-linear, SNR=%.3fdB", snr(f,fnlin));
imageplot(FWT.clamp(fLin),u1, 1,2,1 );
imageplot(clamp(fnlin),u2, 1,2,2 );


text:
# Model
include_model("cartpole")
μ0 = 0.1 # coefficient of friction

model_nominal = CartpoleFriction{Midpoint, FixedTime}(n, m, d,
    1.0, 0.2, 0.5, 9.81, 0.0)
model_friction = CartpoleFriction{Midpoint, FixedTime}(n, m, d,
    1.0, 0.2, 0.5, 9.81, μ0)

# Horizon
T = 51
tf = 5.0
h = tf / (T-1)

# Bounds
ul_friction = zeros(7)
ul_friction[1] = -10.0
uu_friction = Inf * ones(7)
uu_friction[1] = 10.0

ul, uu = control_bounds(model, T, ul_friction, uu_friction)

# Initial and final states
x1 = [0.0; 0.0; 0.0; 0.0]
xT = [0.0; π; 0.0; 0.0]

xl, xu = state_bounds(model, T, x1 = x1, xT = xT)

# Objective
obj = quadratic_tracking_objective(
    [(t < T ? Diagonal(ones(model_nominal.n))
        : Diagonal(zeros(model_nominal.n))) for t = 1:T],
    [Diagonal([0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) for t = 1:T-1],
    [xT for t = 1:T],
    [zeros(model_nominal.m) for t = 1:T])

penalty_obj = PenaltyObjective(1000.0, 7)

multi_obj = MultiObjective([obj, penalty_obj])

# Constraints
include_constraints("friction")

n_stage = 5
con_friction = FrictionConstraints(n_stage * (T - 1),
    vcat([(t - 1) * n_stage .+ (3:5) for t = 1:T-1]...),
    n_stage)

# Problem
prob_nominal = trajectory_optimization_problem(model_nominal,
                    multi_obj,
                    T,
                    xl = xl,
                    xu = xu,
                    ul = ul,
                    uu = uu,
                    h = h,
                    con = con_friction)

prob_friction = trajectory_optimization_problem(model_friction,
                    multi_obj,
                    T,
                    xl = xl,
                    xu = xu,
                    ul = ul,
                    uu = uu,
                    h = h,
                    con = con_friction)

# Trajectory initialization
x0 = linear_interpolation(x1, xT, T) # linear interpolation on stateF
u0 = [ones(model_nominal.m) for t = 1:T-1]

# Pack trajectories into vector
z0 = pack(x0, u0, prob_nominal)

# Solve nominal problem
if false
    @time z̄_nominal, info = solve(prob_nominal, copy(z0),
        tol = 1.0e-5, c_tol = 1.0e-5)
    @time z̄_friction, info = solve(prob_friction, copy(z0),
        tol = 1.0e-5, c_tol = 1.0e-5)
    @save joinpath(@__DIR__, "sol_to.jld2") z̄_nominal z̄_friction
else
    println("Loading solution...")
    @load joinpath(@__DIR__, "sol_to.jld2") z̄_nominal z̄_friction
end


text:
using LinearAlgebra

function so3ToVec(so3mat)
    if( size(so3mat)!=(3,3) )
        println("!Warning! : Input matrix should be 3x3.")
        return
    end
    if( !((so3mat[1,1]==so3mat[2,2]==so3mat[3,3]==0)) )
        println("!Warning! : Diagonals should be zero.")
        return
    end
    if( so3mat[2,1]!=-so3mat[1,2] ||
        so3mat[3,1]!=-so3mat[1,3] ||
        so3mat[3,2]!=-so3mat[2,3] )
        println("!Warning! : Entered matrix isn't a skew symmetric matrix.")
        return
    end
    ret_vec = [so3mat[3,2];
               so3mat[1,3];
               so3mat[2,1] ]
        return ret_vec
end

function vecToSo3(omg)
    if( size(omg)!=(3,) )
        println("!Warning! : Input matrix should be 3x1.")
        return
    end

    ret_ss_matrix = [0      -omg[3]   omg[2];
                     omg[3]    0     -omg[1];
                    -omg[2]  omg[1]      0];
    return ret_ss_matrix
end

using LinearAlgebra

function so3ToVec(so3mat)
    if( size(so3mat)!=(3,3) )
        println("!Warning! : Input matrix should be 3x3.")
        return
    end
    if( !((so3mat[1,1]==so3mat[2,2]==so3mat[3,3]==0)) )
        println("!Warning! : Diagonals should be zero.")
        return
    end
    if( so3mat[2,1]!=-so3mat[1,2] ||
        so3mat[3,1]!=-so3mat[1,3] ||
        so3mat[3,2]!=-so3mat[2,3] )
        println("!Warning! : Entered matrix isn't a skew symmetric matrix.")
        return
    end
    ret_vec = [so3mat[3,2];
               so3mat[1,3];
               so3mat[2,1] ]
        return ret_vec
end

function VecToso3(omg)
    if( size(omg)!=(3,) )
        println("!Warning! : Input matrix should be 3x1.")
        return
    end

    ret_ss_matrix = [0      -omg[3]   omg[2];
                     omg[3]    0     -omg[1];
                    -omg[2]  omg[1]      0];
    return ret_ss_matrix
end
#****************************************************************#
# VeysiADN 17 Apr 2021
# Advanced Robotics Homework 4 Codes
#****************************************************************#
using LinearAlgebra
const lAlgebra = LinearAlgebra
#****************************************************************#
# Returns normalized version of given matrix/array
function Normalize(N)
    return N/lAlgebra.norm(N)
end
#****************************************************************#
# Returns 4x4 twist matrix ‘se3mat’ (an element of Lie Algebra se3)
# from given twist vector (= 6x1 vector) ‘xi
function VecTose3( xi )
    w_skew = [ 0   -xi[3]   xi[2];
              xi[3]   0    -xi[1];
             -xi[2]  xi[1]    0 ]
    return vcat(hcat(w_skew,xi[4:6]), zeros(1, 4))
end
#****************************************************************#
# Returns twist vector ‘xi’ from given twist matrix ‘se3mat’
function se3ToVec( se3mat )
    omg = [se3mat[3, 2], se3mat[1, 3],se3mat[2, 1]]
    v = se3mat[1:3, 4]
    return vcat(omg,v)
end
#****************************************************************#
# Calculates and return rotation matrix ‘R’ by
# evaluating matrix exponential of 3x3 skew symmetric matrix ‘so3mat’

function MatrixExp3(so3mat)
        omg = [so3mat[3, 2], so3mat[1, 3],so3mat[2, 1]]
        theta = lAlgebra.norm(omg)
        omg_n = so3mat / theta
        return lAlgebra.I + sin(theta) * omg_n + (1 - cos(theta)) * omg_n * omg_n
end

#****************************************************************#
# Calculates and return transformation matrix ‘g’ by
# evaluating matrix exponential of 4x4 twist matrix ‘se3mat’
function MatrixExp6( se3mat )
    omg = [se3mat[3, 2], se3mat[1, 3],se3mat[2, 1]]
    theta = norm(omg)
    if theta==0
        return vcat(hcat(I, se3mat[1:3, 4]), [0 0 0 1])
    else
    omg_n = se3mat[1:3, 1:3] / theta
    temp  = hcat(MatrixExp3(se3mat[1:3, 1:3]),
                         (I * theta +
                          (1 - cos(theta)) * omg_n +
                          (theta - sin(theta)) * omg_n * omg_n) *
                         se3mat[1:3, 4] / theta)
    end
    return    vcat(temp,[0 0 0 1])
end

#****************************************************************#
# VeysiADN 12 May 2021
# Advanced Robotics Homework 5 Codes
#****************************************************************#
using LinearAlgebra
const lAlgebra = LinearAlgebra
#****************************************************************#
# Computes exponential coordinate ‘so3mat’
# (skew symmetric matrix) of the rotation matrix R

function MatrixLog3(R)
    acosinput = (lAlgebra.tr(R) - 1) / 2
    if acosinput >= 1
        return zeros(3, 3)
    else
        theta = acos(acosinput)
        return theta / 2 / sin(theta) * (R - R')
    end
end
#****************************************************************#
# Computes exponential coordinate ‘se3mat’
# (twist matrix) of the rigid body transformation matrix T
function MatrixLog6(T)
    if( size(T)!=(4,4) )
        println("!Warning! : Transformation matrix should be 4x4.")
        return
    end
    R = T[1:3,1:3]
    t = T[1:3,4]
    omg_h = MatrixLog3(R)
    w = [omg_h[3,2];omg_h[1,3];omg_h[2,1]]
    if omg_h == zeros(3, 3)
        return vcat(hcat(zeros(3, 3), T[1:3, 4]), [0 0 0 0])
    else
        theta = acos((lAlgebra.tr(R) - 1) / 2)
        return vcat(hcat(omg_h,
                         (I - omg_h / 2 +
                          (1 / theta - 1 / tan(theta / 2) / 2) *
                          omg_h * omg_h / theta) * T[1:3, 4]),
                    [0 0 0 0])
    end
end
#****************************************************************#

#****************************************************************#
# VeysiADN 12 May 2021
# Advanced Robotics Homework 5 Codes
#****************************************************************#
using LinearAlgebra
#****************************************************************#
# Returns Adjoint matrix with given rigid body
# transformation matrix g
function Adjoint(g)

    R=g[1:3,1:3];
    p=g[1:3,4];
    p_hat = [ 0       -p[3]     p[2];
             p[3]       0      -p[1];
            -p[2]      p[1]       0 ]

    return [R zeros(3,3);p_hat*R R]
end
#****************************************************************#
# VeysiADN 4 Apr 2021
# Advanced Robotics Homework 3 Codes
#****************************************************************#
using LinearAlgebra
#****************************************************************#
# Returns 3 x 3 rotation matrix representing
# rotation about unit vector w by angle theta.
# theta should be in radian
function Rodrigues(w,theta)
    if( length(w) != 3)
        println("!Warning! : W matrix should have 3 elements.")
        return
    end
    if(size(w)==(1,3))
        w=w';
    end
    w_hat = [0      -w[3]    w[2];
             w[3]     0     -w[1];
            -w[2]    w[1]      0];
    rotation_matrix = cos(theta)*Matrix(1I,3,3) + sin(theta)*w_hat+(1-cos(theta))*w*w';
    return rotation_matrix;
end
#****************************************************************#
# Builds rigid transformation matrix T from given
#rotation matrix R and translation t
function RpToTrans(R,t)
    if( size(R)!=(3,3) )
        println("!Warning! : Rotation matrix should be 3x3.")
        return
    end
    if( length(t) != 3 )
        println("!Warning! : Translation matrix should have 3 elements.")
        return
    end
    if(size(t)==(1,3))
        t=t';
    end
    R_B_T = hcat(R,t) ;
    R_B_T = vcat(R_B_T,[0 0 0 1]) ;
    return R_B_T
end
#****************************************************************#
#Extracts rotation matrix R and translation t from given /
# rigid transformation matrix T
function TransToRp(T)
    if( size(T)!=(4,4) )
        println("!Warning! : Transformation matrix should be 4x4.")
        return
    end
    R = T[1:3,1:3]
    t = T[1:3,4]
    return R,t;
end
#****************************************************************#
# Inverts rigid transformation matrix T
function TransInv(T)
    if( size(T)!=(4,4) )
        println("!Warning! : W matrix should be 4x4.")
        return
    end
    if( det(T)==0 )
        println("!Warning! : Inverse doesn't exist (Determinant is equal to zero).")
        return
    end
    R,t = TransToRp(T);
    r_inv =hcat(R',-(R'*t))
    r_inv = vcat(r_inv,[0 0 0 1]);
    return r_inv;
end
#****************************************************************#
#  Starting from here  is homework 7.
"""
    Calculates Spatial geometric Jacobian Js, given 6 x n matrix
    ‘Twists’ whose columns are Twist parameter of each joints
    and n x 1 vector of joint angles
"""
function JacobianSpace(Twists, JointAngles)
    T = I;
    Js = Twists
    for i = 2:length(JointAngles)
        T *= MatrixExp6(VecTose3(Twists[:, i - 1] * JointAngles[i - 1]))
        Js[:, i] = Adjoint(T) * Twists[:, i]
    end
    return Js
end
"""
Calculates Forward Kinematics given initial configuration M,
6 x n matrix ‘Twists’ whose columns are twist parameter
of each joints, and n x 1 joint angles
"""
function FwdKin(M,Twists,JointAngles)
    T=M
    for i = length(JointAngles):-1:1
        T = MatrixExp6(VecTose3(Twists[:,i]*JointAngles[i])) * T
    end
    return T
end
"""
Solves Paden-Kahan subproblem 1

"""
function PadenKahanFirst(w, x, y)
    p = x
    q = y
    u = p - (w'*p)*w;
    v = q - (w'*q)*w;
    theta = atan((w'*(cross(u,v)))/(u'*v))
    return theta
end
"""
Solves Paden-Kahan subproblem 2. th will be 2 x 2 matrix
containing solution pair (th1, th2) each row
"""

function PadenKahanSecond(w1, w2, x, y)
    p=x
    q=y

    A = [1 w1'*w2;
        w1'*w2 1];
    B=[w1'*q; w2'*p]
    alfa,beta = A\B

    gamma_sq = ((norm(p)^2)-(alfa^2)-(beta^2)-(2*alfa*beta*(w1'*w2)))/((norm(cross(w1,w2)))^2)
    gamma_1 = sqrt.(gamma_sq);
    gamma_2 = -sqrt.(gamma_sq);
    c_1 = alfa*w1+beta*w2+gamma_1*(cross(w1,w2));
    c_2 = alfa*w1+beta*w2+gamma_2*(cross(w1,w2));
    th_1 = PadenKahanFirst(w2,p,c_1)
    th_2 = PadenKahanFirst(w2,p,c_2)
    th_3 = PadenKahanFirst(-w1,q,c_1)
    th_4 = PadenKahanFirst(-w1,q,c_2)
    th = [th_1 th_3;th_4 th_2];
    return th
end

max_stars_repo_name: veysiadn/AdvancedRoboticsJulia

max_issues_repo_name: veysiadn/AdvancedRoboticsJulia

max_forks_repo_name: veysiadn/AdvancedRoboticsJulia


text:
using HypothesisTests, Distributions, Test, Random
using HypothesisTests: default_tail

@testset "Anderson-Darling" begin
@testset "One sample test" begin
    n = 1000
    Random.seed!(1984948)

    x = rand(Normal(), n)
    t = OneSampleADTest(x, Normal())
    @test t.A² ≈ 0.2013 atol=0.1^4
    @test pvalue(t) ≈ 0.99 atol=0.1^4
    @test default_tail(t) == :right

    x = rand(DoubleExponential(), n)
    t = OneSampleADTest(x, Normal())
    @test t.A² ≈ 10.7439 atol=0.1^4
    @test pvalue(t) ≈ 0.0 atol=0.1^4

    x = rand(Cauchy(), n)
    t = OneSampleADTest(x, Normal())
    @test pvalue(t) ≈ 0.0 atol=0.1^4

    x = rand(LogNormal(), n)
    t = OneSampleADTest(x, Normal())
    @test pvalue(t) ≈ 0.0 atol=0.1^4

    x = rand(Uniform(), n)
    t = OneSampleADTest(x, Uniform())
    @test pvalue(t) ≈ 0.145 atol=0.1^4

    x = rand(Uniform(0, 1.8), n)
    t = OneSampleADTest(x, Uniform())
    @test pvalue(t) ≈ 0.5112 atol=0.1^4

    x = rand(Exponential(), n)
    t = OneSampleADTest(x, Exponential())
    @test pvalue(t) ≈ 0.9427 atol=0.1^4
end

@testset "k-sample test" begin
    Random.seed!(948574875)
    samples = Any[
        [38.7, 41.5, 43.8, 44.5, 45.5, 46.0, 47.7, 58.0],
        [39.2, 39.3, 39.7, 41.4, 41.8, 42.9, 43.3, 45.8],
        [34.0, 35.0, 39.0, 40.0, 43.0, 43.0, 44.0, 45.0],
        [34.0, 34.8, 34.8, 35.4, 37.2, 37.8, 41.2, 42.8]
    ]

    t = KSampleADTest(samples...)
    @test t.A²k ≈ 8.3926 atol=0.1^4
    @test t.σ ≈ 1.2038 atol=0.1^4
    @test pvalue(t) ≈ 0.0022 atol=0.1^4
    @test default_tail(t) == :right

    ts = KSampleADTest(samples..., nsim = 20000);
    @test pvalue(ts) ≈ 0.00155 atol=0.1^3

    t = KSampleADTest(samples..., modified = false)
    @test t.A²k ≈ 8.3559 atol=0.1^4
    @test t.σ ≈ 1.2038 atol=0.1^4
    @test pvalue(t) ≈ 0.0023 atol=0.1^4

    ts = KSampleADTest(samples..., modified = false, nsim = 20000);
    @test pvalue(ts) ≈ 0.00150 atol=0.1^3
end

@testset "more tests" begin
    Random.seed!(31412455)
    samples = Any[rand(Normal(), 50), rand(Normal(0.5), 30)]
    t = KSampleADTest(samples...)
    @test pvalue(t) < 0.05

    samples = Any[rand(Normal(), 50), rand(Normal(), 30), rand(Normal(), 20)]
    t = KSampleADTest(samples...)
    @test pvalue(t) > 0.05

    @test pvalue(OneSampleADTest(vcat(rand(Normal(),500), rand(Beta(2,2),500)), Beta(2,2))) ≈ 0.0 atol=0.1^4

    n = 1000
    x = rand(Exponential(), n)
    @test pvalue(KSampleADTest(rand(1000),randn(1000))) ≈ 0.0 atol=eps()
    @test pvalue(KSampleADTest(x,x,x,x,x,x)) ≈ 1.0
end

end


text:
using CompileBot

# using runtests:
snoop_bot(BotConfig("TestPackage1", tmin =0.0))


text:
# Test name methods
@testset "Infinite Variable Name" begin
    # initialize model and infinite variable
    m = InfiniteModel()
    info = VariableInfo(false, 0, false, 0, false, 0, false, 0, false, false)
    param = InfOptParameter(IntervalSet(0, 1), Number[], false)
    pref = add_parameter(m, param, "test1")
    pref2 = add_parameter(m, param, "test2")
    var = InfiniteVariable(info, (pref, pref2))
    m.vars[1] = var
    m.var_to_name[1] = "var"
    vref = InfiniteVariableRef(m, 1)
    # JuMP.name
    @testset "JuMP.name" begin
        @test name(vref) == "var"
    end
    # parameter_refs
    @testset "parameter_refs" begin
        @test parameter_refs(vref) == (pref, pref2)
    end
    # JuMP.set_name
    @testset "JuMP.set_name" begin
        # make extra infinite variable
        vref2 = InfiniteVariableRef(m, 2)
        m.vars[2] = var
        # test normal
        @test isa(set_name(vref, "new"), Nothing)
        @test name(vref) == "new(test1, test2)"
        # test default
        @test isa(set_name(vref2, ""), Nothing)
        @test name(vref2) == "noname(test1, test2)"
    end
    # _make_variable_ref
    @testset "_make_variable_ref" begin
        @test InfiniteOpt._make_variable_ref(m, 1) == vref
    end
    # parameter_by_name
    @testset "JuMP.variable_by_name" begin
        # test normal
        @test variable_by_name(m, "new(test1, test2)") == vref
        @test isa(variable_by_name(m, "test(test1, test2)"), Nothing)
        # prepare variable with same name
        m.vars[2] = var
        m.var_to_name[2] = "new(test1, test2)"
        m.name_to_var = nothing
        # test multiple name error
        @test_throws ErrorException variable_by_name(m, "new(test1, test2)")
    end
    # _root_name
    @testset "_root_name" begin
        @test InfiniteOpt._root_name(vref) == "new"
    end
end

# Test variable definition methods
@testset "Infinite Variable Definition" begin
    # initialize model and infinite variable info
    m = InfiniteModel()
    param = InfOptParameter(IntervalSet(0, 1), Number[], false)
    pref = add_parameter(m, param, "test")
    pref2 = add_parameter(m, param, "θ")
    prefs = @infinite_parameter(m, x[1:2], set = IntervalSet(0, 1))
    info = VariableInfo(false, 0, false, 0, false, 0, false, 0, false, false)
    info2 = VariableInfo(true, 0, true, 0, true, 0, true, 0, true, false)
    info3 = VariableInfo(true, 0, true, 0, true, 0, true, 0, false, true)
    # _check_parameter_tuple
    @testset "_check_parameter_tuple" begin
        @test isa(InfiniteOpt._check_parameter_tuple(error, (pref, prefs)),
                  Nothing)
        @test_throws ErrorException InfiniteOpt._check_parameter_tuple(error,
                                                               (pref, prefs, 2))
    end
    # _make_formatted_tuple
    @testset "_make_formatted_tuple" begin
        @test isa(InfiniteOpt._make_formatted_tuple((pref, prefs)), Tuple)
        @test isa(InfiniteOpt._make_formatted_tuple((pref, prefs))[2],
                  JuMP.Containers.SparseAxisArray)
        @test isa(InfiniteOpt._make_formatted_tuple((pref, prefs))[1],
                  ParameterRef)
    end
    # _check_tuple_groups
    @testset "_check_tuple_groups" begin
        # prepare param tuple
        tuple = InfiniteOpt._make_formatted_tuple((pref, prefs))
        # test normal
        @test isa(InfiniteOpt._check_tuple_groups(error, tuple), Nothing)
        # prepare bad param tuple
        tuple = InfiniteOpt._make_formatted_tuple(([pref; pref2], prefs))
        # test for errors
        @test_throws ErrorException InfiniteOpt._check_tuple_groups(error,
                                                                    tuple)
        @test_throws ErrorException InfiniteOpt._check_tuple_groups(error,
                                                                   (pref, pref))
    end
    # _make_variable
    @testset "_make_variable" begin
        # test for each error message
        @test_throws ErrorException InfiniteOpt._make_variable(error, info, Val(Infinite),
                                                   bob = 42)
        @test_throws ErrorException InfiniteOpt._make_variable(error, info, :bad)
        @test_throws ErrorException InfiniteOpt._make_variable(error, info, Val(Infinite))
        @test_throws ErrorException InfiniteOpt._make_variable(error, info, Val(Infinite),
                                                   parameter_refs = (pref, 2))
        @test_throws ErrorException InfiniteOpt._make_variable(error, info, Val(Infinite),
                                                  parameter_refs = (pref, pref))
        # defined expected output
        expected = InfiniteVariable(info, (pref,))
        # test for expected output
        @test InfiniteOpt._make_variable(error, info, Val(Infinite),
                             parameter_refs = pref).info == expected.info
        @test InfiniteOpt._make_variable(error, info, Val(Infinite),
                parameter_refs = pref).parameter_refs == expected.parameter_refs
        # test various types of param tuples
        @test InfiniteOpt._make_variable(error, info, Val(Infinite),
                 parameter_refs = (pref, pref2)).parameter_refs == (pref, pref2)
        tuple = InfiniteOpt._make_formatted_tuple((pref, prefs))
        @test InfiniteOpt._make_variable(error, info, Val(Infinite),
                         parameter_refs = (pref, prefs)).parameter_refs == tuple
        tuple = InfiniteOpt._make_formatted_tuple((prefs,))
        @test InfiniteOpt._make_variable(error, info, Val(Infinite),
                             parameter_refs = prefs).parameter_refs == tuple
    end
    # build_variable
    @testset "JuMP.build_variable" begin
        # test for each error message
        @test_throws ErrorException build_variable(error, info, Infinite,
                                                   bob = 42)
        @test_throws ErrorException build_variable(error, info, :bad)
        @test_throws ErrorException build_variable(error, info, Point,
                                                   parameter_refs = pref)
        @test_throws ErrorException build_variable(error, info, Infinite)
        @test_throws ErrorException build_variable(error, info, Infinite,
                                                   parameter_refs = (pref, 2))
        @test_throws ErrorException build_variable(error, info, Infinite,
                                                  parameter_refs = (pref, pref),
                                                  error = error)
        # defined expected output
        expected = InfiniteVariable(info, (pref,))
        # test for expected output
        @test build_variable(error, info, Infinite,
                             parameter_refs = pref).info == expected.info
        @test build_variable(error, info, Infinite,
                parameter_refs = pref).parameter_refs == expected.parameter_refs
        # test various types of param tuples
        @test build_variable(error, info, Infinite,
                 parameter_refs = (pref, pref2)).parameter_refs == (pref, pref2)
        tuple = InfiniteOpt._make_formatted_tuple((pref, prefs))
        @test build_variable(error, info, Infinite,
                         parameter_refs = (pref, prefs)).parameter_refs == tuple
        tuple = InfiniteOpt._make_formatted_tuple((prefs,))
        @test build_variable(error, info, Infinite,
                             parameter_refs = prefs).parameter_refs == tuple
    end
    # _update_param_var_mapping
    @testset "_update_param_var_mapping" begin
        # initialize secondary model and infinite variable
        m2 = InfiniteModel()
        param = InfOptParameter(IntervalSet(0, 1), Number[], false)
        pref3 = add_parameter(m2, param, "test")
        prefs2 = @infinite_parameter(m2, x[1:2], set = IntervalSet(0, 1))
        ivref = InfiniteVariableRef(m2, 1)
        ivref2 = InfiniteVariableRef(m2, 2)
        # prepare tuple
        tuple = (pref3, prefs2)
        tuple = InfiniteOpt._make_formatted_tuple(tuple)
        # test normal
        @test isa(InfiniteOpt._update_param_var_mapping(ivref, tuple), Nothing)
        @test m2.param_to_vars[1] == [1]
        @test m2.param_to_vars[2] == [1]
        @test m2.param_to_vars[3] == [1]
        @test isa(InfiniteOpt._update_param_var_mapping(ivref2, tuple), Nothing)
        @test m2.param_to_vars[1] == [1, 2]
        @test m2.param_to_vars[2] == [1, 2]
        @test m2.param_to_vars[3] == [1, 2]
    end
    # _check_parameters_valid
    @testset "_check_parameters_valid" begin
        # prepare param tuple
        tuple = (pref, prefs, copy(pref2, InfiniteModel()))
        tuple = InfiniteOpt._make_formatted_tuple(tuple)
        # test that catches error
        @test_throws ErrorException InfiniteOpt._check_parameters_valid(m, tuple)
        # test normal
        @test isa(InfiniteOpt._check_parameters_valid(m, (pref, pref2)), Nothing)
    end
    # _check_make_variable_ref
    @testset "_check_make_variable_ref" begin
        # prepare secondary model and parameter and variable
        m2 = InfiniteModel()
        param = InfOptParameter(IntervalSet(0, 1), Number[], false)
        pref3 = add_parameter(m2, param, "test")
        v = build_variable(error, info, Infinite,
                           parameter_refs = pref3)
        # test for error of invalid variable
        @test_throws ErrorException InfiniteOpt._check_make_variable_ref(m, v)
        # prepare normal variable
        v = build_variable(error, info, Infinite, parameter_refs = pref)
        # test normal
        @test InfiniteOpt._check_make_variable_ref(m, v) == InfiniteVariableRef(m, 0)
        @test m.param_to_vars[1] == [0]
        delete!(m.param_to_vars, 1)
        # test with other variable object
        @test_throws ErrorException InfiniteOpt._check_make_variable_ref(m, :bad)
    end
    # add_variable
    @testset "JuMP.add_variable" begin
        # prepare secondary model and parameter and variable
        m2 = InfiniteModel()
        param = InfOptParameter(IntervalSet(0, 1), Number[], false)
        pref3 = add_parameter(m2, param, "test")
        v = build_variable(error, info, Infinite,
                           parameter_refs = pref3)
        # test for error of invalid variable
        @test_throws ErrorException add_variable(m, v)
        # prepare normal variable
        v = build_variable(error, info, Infinite, parameter_refs = pref)
        # test normal
        @test add_variable(m, v, "name") == InfiniteVariableRef(m, 2)
        @test haskey(m.vars, 2)
        @test m.param_to_vars[1] == [2]
        @test m.var_to_name[2] == "name(test)"
        # prepare infinite variable with all the possible info additions
        v = build_variable(error, info2, Infinite, parameter_refs = pref)
        # test info addition functions
        vref = InfiniteVariableRef(m, 3)
        @test add_variable(m, v, "name") == vref
        @test !optimizer_model_ready(m)
        # lower bound
        @test has_lower_bound(vref)
        @test JuMP._lower_bound_index(vref) == 1
        @test isa(m.constrs[1], ScalarConstraint{InfiniteVariableRef,
                                                 MOI.GreaterThan{Float64}})
        @test m.constr_in_var_info[1]
        # upper bound
        @test has_upper_bound(vref)
        @test JuMP._upper_bound_index(vref) == 2
        @test isa(m.constrs[2], ScalarConstraint{InfiniteVariableRef,
                                                 MOI.LessThan{Float64}})
        @test m.constr_in_var_info[2]
        # fix
        @test is_fixed(vref)
        @test JuMP._fix_index(vref) == 3
        @test isa(m.constrs[3], ScalarConstraint{InfiniteVariableRef,
                                                 MOI.EqualTo{Float64}})
        @test m.constr_in_var_info[3]
        # binary
        @test is_binary(vref)
        @test JuMP._binary_index(vref) == 4
        @test isa(m.constrs[4], ScalarConstraint{InfiniteVariableRef,
                                                 MOI.ZeroOne})
        @test m.constr_in_var_info[4]
        @test m.var_to_constrs[3] == [1, 2, 3, 4]
        # prepare infinite variable with integer info addition
        v = build_variable(error, info3, Infinite, parameter_refs = pref)
        # test integer addition functions
        vref = InfiniteVariableRef(m, 4)
        @test add_variable(m, v, "name") == vref
        @test !optimizer_model_ready(m)
        @test is_integer(vref)
        @test JuMP._integer_index(vref) == 8
        @test isa(m.constrs[8], ScalarConstraint{InfiniteVariableRef,
                                                 MOI.Integer})
        @test m.constr_in_var_info[8]
        @test m.var_to_constrs[4] == [5, 6, 7, 8]
    end
end

# Test name methods
@testset "Point Variable Name" begin
    # initialize model and point variable
    m = InfiniteModel()
    info = VariableInfo(false, 0, false, 0, false, 0, false, 0, false, false)
    param = InfOptParameter(IntervalSet(0, 1), Number[], false)
    pref = add_parameter(m, param, "test1")
    pref2 = add_parameter(m, param, "test2")
    ivar = InfiniteVariable(info, (pref, pref2))
    ivref = add_variable(m, ivar, "ivar")
    var = PointVariable(info, ivref, (0.5, 0.5))
    m.vars[2] = var
    m.var_to_name[2] = "var"
    vref = PointVariableRef(m, 2)
    # JuMP.name
    @testset "JuMP.name" begin
        @test name(vref) == "var"
    end
    # infinite_variable_ref
    @testset "infinite_variable_ref" begin
        @test infinite_variable_ref(vref) == ivref
    end
    # _make_str_value (Number)
    @testset "_make_str_value (Number)" begin
        @test InfiniteOpt._make_str_value(1.0) == "1"
    end
    # _make_str_value (Array)
    @testset "_make_str_value (Array)" begin
        # test short array
        values = convert(JuMPC.SparseAxisArray, [1., 2., 3.])
        @test InfiniteOpt._make_str_value(values) == "[1, 2, 3]"
        # test long array
        values = convert(JuMPC.SparseAxisArray, [1., 2., 3., 4., 5., 6.])
        @test InfiniteOpt._make_str_value(values) == "[1, ..., 6]"
    end
    # JuMP.set_name
    @testset "JuMP.set_name" begin
        # prepare a secondary point variable
        vref2 = PointVariableRef(m, 3)
        m.vars[3] = var
        # test normal
        @test isa(set_name(vref, "new"), Nothing)
        @test name(vref) == "new"
        # test default
        @test isa(set_name(vref2, ""), Nothing)
        @test name(vref2) == "ivar(0.5, 0.5)"
        # test other default
        m.next_var_index = 3
        ivref2 = add_variable(m, InfiniteVariable(info, (pref,)), "ivar2")
        m.vars[5] = PointVariable(info, ivref2, (0.5,))
        m.var_to_name[5] = "var42"
        vref3 = PointVariableRef(m, 5)
        @test isa(set_name(vref3, ""), Nothing)
        @test name(vref3) == "ivar2(0.5)"
    end
    # _make_variable_ref
    @testset "_make_variable_ref" begin
        @test InfiniteOpt._make_variable_ref(m, 2) == vref
    end
    # parameter_by_name
    @testset "JuMP.variable_by_name" begin
        # test normal
        @test variable_by_name(m, "new") == vref
        @test isa(variable_by_name(m, "test"), Nothing)
        # make variable with duplicate name
        m.vars[3] = var
        m.var_to_name[3] = "new"
        m.name_to_var = nothing
        # test for multiple name error
        @test_throws ErrorException variable_by_name(m, "new")
    end
end

# Test variable definition methods
@testset "Point Variable Definition" begin
    # initialize model and infinite variables
    m = InfiniteModel()
    param = InfOptParameter(IntervalSet(0, 1), Number[], false)
    pref = add_parameter(m, param, "test")
    pref2 = add_parameter(m, param, "θ")
    prefs = @infinite_parameter(m, x[1:2], set = IntervalSet(0, 1))
    info = VariableInfo(false, 0., false, 0., false, 0., false, NaN, false, false)
    info2 = VariableInfo(true, 0, true, 0, true, 0, true, 0, true, false)
    info3 = VariableInfo(true, 0, true, 0, true, 0, true, 0, false, true)
    ivar = InfiniteVariable(info, (pref, pref2))
    ivref = add_variable(m, ivar, "ivar")
    ivar2 = build_variable(error, info, Infinite, parameter_refs = (pref, prefs))
    ivref2 = add_variable(m, ivar2, "ivar2")
    # _check_tuple_shape
    @testset "_check_tuple_shape" begin
        # test normal
        @test isa(InfiniteOpt._check_tuple_shape(error, ivref, (0.5, 0.5)),
                  Nothing)
        # prepare param value tuple
        tuple = InfiniteOpt._make_formatted_tuple((0.5, [0.5, 0.5]))
        # test normal with array
        @test isa(InfiniteOpt._check_tuple_shape(error, ivref2, tuple), Nothing)
        # test for errors in shape
        @test_throws ErrorException InfiniteOpt._check_tuple_shape(error, ivref,
                                                                   (0.5,))
        @test_throws ErrorException InfiniteOpt._check_tuple_shape(error, ivref,
                                                                   (0.5, [0.5]))
        @test_throws ErrorException InfiniteOpt._check_tuple_shape(error, ivref2,
                                                                   (0.5, 0.5))
        tuple = InfiniteOpt._make_formatted_tuple((0.5, [0.5, 0.5, 0.5]))
        @test_throws ErrorException InfiniteOpt._check_tuple_shape(error, ivref2,
                                                                   tuple)
    end
    # _check_tuple_values
    @testset "_check_tuple_values" begin
        # test normal
        @test isa(InfiniteOpt._check_tuple_values(error, ivref, (0.5, 0.5)),
                  Nothing)
        # prepare array test
        tuple = InfiniteOpt._make_formatted_tuple((0, [0.5, 1]))
        # test normal with array
        @test isa(InfiniteOpt._check_tuple_values(error, ivref2, tuple), Nothing)
        # test for out of bound errors
        @test_throws ErrorException InfiniteOpt._check_tuple_values(error, ivref,
                                                                    (0, 2))
        tuple = InfiniteOpt._make_formatted_tuple((0, [2, 1]))
        @test_throws ErrorException InfiniteOpt._check_tuple_values(error, ivref2,
                                                                    tuple)
    end
    # _update_point_info
    @testset "_update_point_info" begin
        # prepare info for test
        new_info = VariableInfo(true, 0., true, 0., false, 0., true, 0., true,
                                false)
        InfiniteOpt._update_variable_info(ivref, new_info)
        # test with current info
        @test InfiniteOpt._update_point_info(info, ivref) == new_info
        # prepare info for test
        new_info = VariableInfo(false, 0., false, 0., true, 0., true, 0., false,
                                true)
        InfiniteOpt._update_variable_info(ivref, new_info)
        # test with current info
        @test InfiniteOpt._update_point_info(info, ivref) == new_info
        # prepare info for test
        curr_info = VariableInfo(true, 0., true, 0., false, 0., true, 0., true,
                                 false)
        # test with current info
        @test InfiniteOpt._update_point_info(curr_info, ivref) == curr_info
        # undo info changes
        InfiniteOpt._update_variable_info(ivref, info)
    end
    # test _make_variable
    @testset "_make_variable" begin
        # test for all errors
        @test_throws ErrorException InfiniteOpt._make_variable(error, info,
                                              Val(Point), parameter_refs = pref)
        @test_throws ErrorException InfiniteOpt._make_variable(error, info,
                                                               Val(Point))
        @test_throws ErrorException InfiniteOpt._make_variable(error, info,
                                      Val(Point), infinite_variable_ref = ivref)
        @test_throws ErrorException InfiniteOpt._make_variable(error, info,
                                               Val(Point), parameter_values = 3)
        # test a variety of builds
        @test InfiniteOpt._make_variable(error, info, Val(Point), infinite_variable_ref = ivref,
                   parameter_values = (0.5, 0.5)).infinite_variable_ref == ivref
        @test InfiniteOpt._make_variable(error, info, Val(Point), infinite_variable_ref = ivref,
                   parameter_values = (0.5, 0.5)).parameter_values == (0.5, 0.5)
        @test InfiniteOpt._make_variable(error, info, Val(Point), infinite_variable_ref = ivref,
                             parameter_values = (0.5, 0.5)).info == info
        @test_throws ErrorException InfiniteOpt._make_variable(error, info, Val(Point),
                                                  infinite_variable_ref = ivref,
                                                  parameter_values = (0.5, 2))
        @test InfiniteOpt._make_variable(error, info, Val(Point), infinite_variable_ref = ivref2,
               parameter_values = (0.5, [0, 0])).infinite_variable_ref == ivref2
        tuple = InfiniteOpt._make_formatted_tuple((0.5, [0, 0]))
        @test InfiniteOpt._make_variable(error, info, Val(Point), infinite_variable_ref = ivref2,
                     parameter_values = (0.5, [0, 0])).parameter_values == tuple
        @test_throws ErrorException InfiniteOpt._make_variable(error, info, Val(Point),
                                            infinite_variable_ref = ivref2,
                                            parameter_values = (0.5, [0, 0, 0]))
    end
    # build_variable
    @testset "JuMP.build_variable" begin
        # test for all errors
        @test_throws ErrorException build_variable(error, info, Infinite,
                                                  infinite_variable_ref = ivref)
        @test_throws ErrorException build_variable(error, info, Infinite,
                                                   parameter_values = 3)
        @test_throws ErrorException build_variable(error, info, Point)
        @test_throws ErrorException build_variable(error, info, Point,
                                                  infinite_variable_ref = ivref)
        @test_throws ErrorException build_variable(error, info, Point,
                                                   parameter_values = 3)
        # test a variety of builds
        @test build_variable(error, info, Point, infinite_variable_ref = ivref,
                   parameter_values = (0.5, 0.5)).infinite_variable_ref == ivref
        @test build_variable(error, info, Point, infinite_variable_ref = ivref,
                   parameter_values = (0.5, 0.5)).parameter_values == (0.5, 0.5)
        @test build_variable(error, info, Point, infinite_variable_ref = ivref,
                             parameter_values = (0.5, 0.5)).info == info
        @test_throws ErrorException build_variable(error, info, Point,
                                                  infinite_variable_ref = ivref,
                                                  parameter_values = (0.5, 2))
        @test build_variable(error, info, Point, infinite_variable_ref = ivref2,
               parameter_values = (0.5, [0, 0])).infinite_variable_ref == ivref2
        tuple = InfiniteOpt._make_formatted_tuple((0.5, [0, 0]))
        @test build_variable(error, info, Point, infinite_variable_ref = ivref2,
                     parameter_values = (0.5, [0, 0])).parameter_values == tuple
        @test_throws ErrorException build_variable(error, info, Point,
                                            infinite_variable_ref = ivref2,
                                            parameter_values = (0.5, [0, 0, 0]))
    end
    # _update_param_supports
    @testset "_update_param_supports" begin
        # test normal
        @test isa(InfiniteOpt._update_param_supports(ivref, (0.5, 1)), Nothing)
        @test supports(pref) == [0.5]
        @test supports(pref2) == [1]
        # prepare array tuple
        tuple = InfiniteOpt._make_formatted_tuple((0.5, [0, 1]))
        # test normal with array
        @test isa(InfiniteOpt._update_param_supports(ivref2, tuple), Nothing)
        @test supports(pref) == [0.5]
        @test supports(prefs[1]) == [0]
        @test supports(prefs[2]) == [1]
    end
    # _update_infinite_point_mapping
    @testset "_update_infinite_point_mapping" begin
        # test first addition
        pvref = PointVariableRef(m, 12)
        @test isa(InfiniteOpt._update_infinite_point_mapping(pvref, ivref),
                  Nothing)
        @test m.infinite_to_points[JuMP.index(ivref)] == [12]
        # test second addition
        pvref = PointVariableRef(m, 42)
        @test isa(InfiniteOpt._update_infinite_point_mapping(pvref, ivref),
                  Nothing)
        @test m.infinite_to_points[JuMP.index(ivref)] == [12, 42]
        # undo changes
        delete!( m.infinite_to_points, JuMP.index(ivref))
    end
    # _check_make_variable_ref
    @testset "_check_make_variable_ref" begin
        # prepare secondary model and infinite variable
        m2 = InfiniteModel()
        pref3 = add_parameter(m2, param, "test")
        ivar3 = InfiniteVariable(info, (pref3,))
        ivref3 = add_variable(m2, ivar3, "ivar")
        v = build_variable(error, info, Point, infinite_variable_ref = ivref3,
                           parameter_values = 0.5)
        # test for invalid variable error
        @test_throws ErrorException InfiniteOpt._check_make_variable_ref(m, v)
        # test normal
        v = build_variable(error, info, Point, infinite_variable_ref = ivref,
                           parameter_values = (0, 1))
        @test InfiniteOpt._check_make_variable_ref(m, v) == PointVariableRef(m, 2)
        @test supports(pref) == [0.5, 0]
        @test supports(pref2) == [1]
        @test m.infinite_to_points[JuMP.index(ivref)] == [2]
        delete!(m.infinite_to_points, JuMP.index(ivref))
    end
    # add_variable
    @testset "JuMP.add_variable" begin
        # prepare secondary model and infinite variable
        m2 = InfiniteModel()
        pref3 = add_parameter(m2, param, "test")
        ivar3 = InfiniteVariable(info, (pref3,))
        ivref3 = add_variable(m2, ivar3, "ivar")
        v = build_variable(error, info, Point, infinite_variable_ref = ivref3,
                           parameter_values = 0.5)
        # test for invalid variable error
        @test_throws ErrorException add_variable(m, v)
        # test normal
        v = build_variable(error, info, Point, infinite_variable_ref = ivref,
                           parameter_values = (0, 1))
        @test add_variable(m, v, "name") == PointVariableRef(m, 4)
        @test haskey(m.vars, 4)
        @test supports(pref) == [0.5, 0]
        @test supports(pref2) == [1]
        @test m.var_to_name[4] == "name"
        @test m.infinite_to_points[JuMP.index(ivref)] == [4]
        # prepare infinite variable with all the possible info additions
        v = build_variable(error, info2, Point, infinite_variable_ref = ivref,
                           parameter_values = (0, 1))
        # test info addition functions
        vref = PointVariableRef(m, 5)
        @test add_variable(m, v, "name") == vref
        @test !optimizer_model_ready(m)
        # lower bound
        @test has_lower_bound(vref)
        @test JuMP._lower_bound_index(vref) == 1
        @test isa(m.constrs[1], ScalarConstraint{PointVariableRef,
                                                 MOI.GreaterThan{Float64}})
        @test m.constr_in_var_info[1]
        # upper bound
        @test has_upper_bound(vref)
        @test JuMP._upper_bound_index(vref) == 2
        @test isa(m.constrs[2], ScalarConstraint{PointVariableRef,
                                                 MOI.LessThan{Float64}})
        @test m.constr_in_var_info[2]
        # fix
        @test is_fixed(vref)
        @test JuMP._fix_index(vref) == 3
        @test isa(m.constrs[3], ScalarConstraint{PointVariableRef,
                                                 MOI.EqualTo{Float64}})
        @test m.constr_in_var_info[3]
        # binary
        @test is_binary(vref)
        @test JuMP._binary_index(vref) == 4
        @test isa(m.constrs[4], ScalarConstraint{PointVariableRef,
                                                 MOI.ZeroOne})
        @test m.constr_in_var_info[4]
        @test m.var_to_constrs[5] == [1, 2, 3, 4]
        # prepare infinite variable with integer info addition
        v = build_variable(error, info3, Point, infinite_variable_ref = ivref,
                           parameter_values = (0, 1))
        # test integer addition functions
        vref = PointVariableRef(m, 6)
        @test add_variable(m, v, "name") == vref
        @test !optimizer_model_ready(m)
        @test is_integer(vref)
        @test JuMP._integer_index(vref) == 8
        @test isa(m.constrs[8], ScalarConstraint{PointVariableRef,
                                                 MOI.Integer})
        @test m.constr_in_var_info[8]
        @test m.var_to_constrs[6] == [5, 6, 7, 8]
    end
end

# Test name methods
@testset "Hold Variable Name" begin
    # initialize model and variable
    m = InfiniteModel()
    info = VariableInfo(false, 0, false, 0, false, 0, false, 0, false, false)
    bounds = ParameterBounds()
    var = HoldVariable(info, bounds)
    m.vars[1] = var
    m.var_to_name[1] = "test"
    vref = HoldVariableRef(m, 1)
    # JuMP.name
    @testset "JuMP.name" begin
        @test name(vref) == "test"
    end
    # JuMP.set_name
    @testset "JuMP.set_name" begin
        @test isa(set_name(vref, "new"), Nothing)
        @test name(vref) == "new"
    end
    # _make_variable_ref
    @testset "_make_variable_ref" begin
        @test InfiniteOpt._make_variable_ref(m, 1) == vref
    end
    # parameter_by_name
    @testset "JuMP.variable_by_name" begin
        # test normal
        @test variable_by_name(m, "new") == vref
        @test isa(variable_by_name(m, "test2"), Nothing)
        # prepare variable with duplicate name
        m.vars[2] = var
        m.var_to_name[2] = "new"
        m.name_to_var = nothing
        # test for duplciate name error
        @test_throws ErrorException variable_by_name(m, "new")
    end
end

# Test variable definition methods
@testset "Hold Variable Definition" begin
    # initialize model and info
    m = InfiniteModel()
    info = VariableInfo(false, 0, false, 0, false, 0, false, 0, false, false)
    info2 = VariableInfo(true, 0, true, 0, true, 0, true, 0, true, false)
    info3 = VariableInfo(true, 0, true, 0, true, 0, true, 0, false, true)
    bounds = ParameterBounds()
    @infinite_parameter(m, 0 <= par <= 10)
    @infinite_parameter(m, 0 <= pars[1:2] <= 10)
    # test _check_bounds
    @testset "_check_bounds" begin
        # test normal
        @test isa(InfiniteOpt._check_bounds(ParameterBounds(Dict(par => IntervalSet(0, 1)))),
                                                                        Nothing)
        # test errors
        @test_throws ErrorException InfiniteOpt._check_bounds(
                                ParameterBounds(Dict(par => IntervalSet(-1, 1))))
        @test_throws ErrorException InfiniteOpt._check_bounds(
                                ParameterBounds(Dict(par => IntervalSet(0, 11))))
    end
    # _make_variable
    @testset "_make_variable" begin
        # test normal
        expected = HoldVariable(info, bounds)
        @test InfiniteOpt._make_variable(error, info, Val(Hold)).info == expected.info
        # test errors
        @test_throws ErrorException InfiniteOpt._make_variable(error, info,
                                                Val(Hold), parameter_values = 3)
    end
    # build_variable
    @testset "JuMP.build_variable" begin
        # test normal
        expected = HoldVariable(info, bounds)
        @test build_variable(error, info, Hold).info == expected.info
        # test errors
        @test_throws ErrorException build_variable(error, info, Point,
                                                   parameter_bounds = bounds)
    end
    # _validate_bounds
    @testset "_validate_bounds" begin
        # test normal
        @test isa(InfiniteOpt._validate_bounds(m,
                      ParameterBounds(Dict(par => IntervalSet(0, 1)))), Nothing)
        # test error
        par2 = ParameterRef(InfiniteModel(), 1)
        @test_throws ErrorException InfiniteOpt._validate_bounds(m,
                               ParameterBounds(Dict(par2 => IntervalSet(0, 1))))
        # test support addition
        @test isa(InfiniteOpt._validate_bounds(m,
                      ParameterBounds(Dict(par => IntervalSet(0, 0)))), Nothing)
        @test supports(par) == [0]
    end
    # _check_make_variable_ref
    @testset "_check_make_variable_ref" begin
        # test normal
        v = build_variable(error, info, Hold)
        @test InfiniteOpt._check_make_variable_ref(m, v) == HoldVariableRef(m, 0)
        # test with bounds
        bounds = ParameterBounds(Dict(par => IntervalSet(0, 2)))
        v = build_variable(error, info, Hold, parameter_bounds = bounds)
        @test InfiniteOpt._check_make_variable_ref(m, v) == HoldVariableRef(m, 0)
        @test m.has_hold_bounds
        m.has_hold_bounds = false
        # test bad bounds
        @infinite_parameter(InfiniteModel(), par2 in [0, 2])
        v = build_variable(error, info, Hold,
            parameter_bounds = ParameterBounds(Dict(par2 => IntervalSet(0, 1))))
        @test_throws ErrorException InfiniteOpt._check_make_variable_ref(m, v)
    end
    # add_variable
    @testset "JuMP.add_variable" begin
        v = build_variable(error, info, Hold)
        @test add_variable(m, v, "name") == HoldVariableRef(m, 1)
        @test haskey(m.vars, 1)
        @test m.var_to_name[1] == "name"
        # prepare infinite variable with all the possible info additions
        v = build_variable(error, info2, Hold)
        # test info addition functions
        vref = HoldVariableRef(m, 2)
        @test add_variable(m, v, "name") == vref
        @test !optimizer_model_ready(m)
        # lower bound
        @test has_lower_bound(vref)
        @test JuMP._lower_bound_index(vref) == 1
        @test isa(m.constrs[1], ScalarConstraint{HoldVariableRef,
                                                 MOI.GreaterThan{Float64}})
        @test m.constr_in_var_info[1]
        # upper bound
        @test has_upper_bound(vref)
        @test JuMP._upper_bound_index(vref) == 2
        @test isa(m.constrs[2], ScalarConstraint{HoldVariableRef,
                                                 MOI.LessThan{Float64}})
        @test m.constr_in_var_info[2]
        # fix
        @test is_fixed(vref)
        @test JuMP._fix_index(vref) == 3
        @test isa(m.constrs[3], ScalarConstraint{HoldVariableRef,
                                                 MOI.EqualTo{Float64}})
        @test m.constr_in_var_info[3]
        # binary
        @test is_binary(vref)
        @test JuMP._binary_index(vref) == 4
        @test isa(m.constrs[4], ScalarConstraint{HoldVariableRef,
                                                 MOI.ZeroOne})
        @test m.constr_in_var_info[4]
        @test m.var_to_constrs[2] == [1, 2, 3, 4]
        # prepare infinite variable with integer info addition
        v = build_variable(error, info3, Hold)
        # test integer addition functions
        vref = HoldVariableRef(m, 3)
        @test add_variable(m, v, "name") == vref
        @test !optimizer_model_ready(m)
        @test is_integer(vref)
        @test JuMP._integer_index(vref) == 8
        @test isa(m.constrs[8], ScalarConstraint{HoldVariableRef,
                                                 MOI.Integer})
        @test m.constr_in_var_info[8]
        @test m.var_to_constrs[3] == [5, 6, 7, 8]
    end
end


text:
using ONNX, Flux, ProtoBuf
using Test

include("ops_tests.jl")

@testset "ONNX" begin

include("conversions.jl")
include("constant.jl")
include("logical_ops.jl")
include("pooling.jl")
include("conv.jl")
include("reshape.jl")
include("arithmetic_ops.jl")
include("lstm.jl")

end


text:
module MaximinOPF
using PowerModels
using Dualization
using MathOptInterface

include("Variables.jl")
include("Objectives.jl")
include("Constraints.jl")
include("utils.jl")
greet() = print("Hello World!")

supported_pm=[
    ACPPowerModel, ACRPowerModel, ACTPowerModel,
    SOCWRPowerModel, SOCWRConicPowerModel,
    SOCBFPowerModel, SOCBFConicPowerModel,
    QCRMPowerModel, QCLSPowerModel,
    SDPWRMPowerModel, SparseSDPWRMPowerModel,
    DCPPowerModel, DCMPPowerModel, NFAPowerModel,
    DCPLLPowerModel, LPACCPowerModel
]
conic_supported_pm=[
    SOCWRConicPowerModel, SOCBFConicPowerModel,
	SDPWRMPowerModel, SparseSDPWRMPowerModel,
    DCPPowerModel, DCMPPowerModel, NFAPowerModel
]
sdp_pm=[ SDPWRMPowerModel, SparseSDPWRMPowerModel ]
nonconvex_pm=[ACPPowerModel, ACRPowerModel, ACTPowerModel]
not_supported_pm=[IVRPowerModel]

function MaximinOPFModel(pm_data, pm_form; enforce_int=true, io=devnull, rm_therm_line_lim=false)
    println(io,"Calling MaximinOPFModel() with pm_form: ",pm_form)
    minmax_pm = MinimaxOPFModel(pm_data, pm_form; rm_therm_line_lim=rm_therm_line_lim)

    #Test Out
    println(io,"name: ", pm_data["name"])
    println(io,"attacker_budget: ", pm_data["attacker_budget"])
    println(io,"inactive_branches: ", pm_data["inactive_branches"])
    println(io,"protected_branches: ", pm_data["protected_branches"])
    println(io, "Model:")
    println(io, minmax_pm.model)

    if pm_form in conic_supported_pm
        maxmin_model = DualizeMinmaxModel(minmax_pm)
        if enforce_int
            for l in minmax_pm.data["undecided_branches"]
                if has_lower_bound(variable_by_name(maxmin_model,"x[$l]_1"))
                    delete_lower_bound(variable_by_name(maxmin_model,"x[$l]_1"))
                end
                if has_upper_bound(variable_by_name(maxmin_model,"x[$l]_1"))
                    delete_upper_bound(variable_by_name(maxmin_model,"x[$l]_1"))
                end
                JuMP.set_integer(variable_by_name(maxmin_model,"x[$l]_1"))
                JuMP.@constraint(maxmin_model, variable_by_name(maxmin_model,"x[$l]_1") >= 0)
                JuMP.@constraint(maxmin_model, variable_by_name(maxmin_model,"x[$l]_1") <= 1)
            end
        end
	    return maxmin_model
    else
        println(Base.stderr,"WARNING: Model type ",pm_form," is either nonconic and/or nonconvex and thus is not currently supported by function MaximinOPFModel().")
	    println(Base.stderr,"\tWARNING: function MaximinOPFModel() is returning the MINMAX model and NOT the MAXMIN model.")
	    return minmax_pm.model
    end
end

function MinimaxOPFModel(pm_data, pm_form; rm_therm_line_lim=false)
    if pm_form in supported_pm
        pm = instantiate_model(pm_data, pm_form, Post_PF)
        variable_ordering_auxiliary(pm)
        con(pm, pm.cnw)[:x] = Dict{Int,JuMP.ConstraintRef}()
        for l in pm.data["undecided_branches"]
            con(pm, pm.cnw)[:x][l] = constraint_abs_branch_flow_ordering(pm, l)
            JuMP.set_name(con(pm, pm.cnw)[:x][l],"x[$l]")
        end
        objective_minmax_problem(pm)
        removeRedundantConstraints(pm)
        if rm_therm_line_lim
	        removeThermalLineLimits(pm)
        else
            replaceThermalLineLimits(pm)
        end
        return pm
    else
        println(Base.stderr,"Not Supported Power Model Option. WARNING: returning 'nothing'")
	    return nothing
    end
end

function PF_FeasModel(pm_data, pm_form; rm_therm_line_lim=false, x_vals::Dict{Int64,Float64}=Dict{Int64,Float64}() )
    if pm_form in supported_pm
        pm = instantiate_model(pm_data, pm_form, Post_PF)
        for l in ids(pm,pm.cnw,:branch)
            if !haskey(x_vals,l)
	            if l in pm_data["inactive_branches"]
		            x_vals[l]=1
	            else
		            x_vals[l]=0
	            end
            end
        end
        objective_feasibility_problem(pm,x_vals)
        removeRedundantConstraints(pm)
        if rm_therm_line_lim
	        removeThermalLineLimits(pm)
        else
            replaceThermalLineLimits(pm)
        end
        return pm
    else
        println(Base.stderr,"PF_FeasModel: ", pm_form," Not Supported Power Model Option. WARNING: returning 'nothing'")
	    return nothing
    end
end

function DualizeMinmaxModel(minmax_model_pm::AbstractPowerModel)
    if typeof(minmax_model_pm) in conic_supported_pm
	    dualizable_minmax_model = ConvertModelToDualizableForm(minmax_model_pm.model)
        AssignModelDefaultConstraintNames(dualizable_minmax_model)
        dualized_minmax_model = dualize(dualizable_minmax_model;dual_names = DualNames("", ""))
        return dualized_minmax_model
    else
        println(Base.stderr,"DualizeMinmaxModel: Not supported for ",typeof(minmax_model_pm)," PowerModels, returning 'nothing'.")
	    return nothing
    end
end

function DualizeMinmaxModel(dualizable_minmax_model::JuMP.Model)
    AssignModelDefaultConstraintNames(dualizable_minmax_model)
    dualized_minmax_model = dualize(dualizable_minmax_model;dual_names = DualNames("", ""))
end

function AssignModelDefaultConstraintNames(model::JuMP.Model)
    all_vars = JuMP.all_variables(model)
    n_vars = length(all_vars)
    var_ids = collect(1:n_vars)
    artificial_lb_var_ids=[]
    artificial_ub_var_ids=[]
    for vv in var_ids
        var_name = JuMP.name(all_vars[vv])
        if JuMP.has_upper_bound(all_vars[vv])
  		    JuMP.set_name(UpperBoundRef(all_vars[vv]), string(var_name,"_UB"))
        end
        if JuMP.has_lower_bound(all_vars[vv])
  		    JuMP.set_name(LowerBoundRef(all_vars[vv]), string(var_name,"_LB"))
        end
    end

    type_str_map = Dict{DataType,String}(
	    VariableRef=>"Var",
	    GenericAffExpr{Float64,VariableRef}=>"Expr",
        Array{GenericAffExpr{Float64,VariableRef},1}=>"VecExpr",
	    MathOptInterface.EqualTo{Float64}=>"EQ",
	    MathOptInterface.GreaterThan{Float64}=>"GE",
	    MathOptInterface.LessThan{Float64}=>"LE",
	    MathOptInterface.SecondOrderCone=>"SOC",
	    MathOptInterface.RotatedSecondOrderCone=>"RSOC",
	    MathOptInterface.PositiveSemidefiniteConeTriangle=>"PSD",
	    MathOptInterface.PositiveSemidefiniteConeSquare=>"PSDSQ",
    )
    con_types=list_of_constraint_types(model)
    n_con_types=length(con_types)
	con_dict = Dict{Tuple{DataType,DataType},Dict{Int64,String}}()

	for kk=1:n_con_types
	  con = all_constraints(model, con_types[kk][1], con_types[kk][2])
	  con_dict[ ( con_types[kk][1],  con_types[kk][2] )  ] = Dict{Int64,String}()
	    n_con=length(con)
	    for jj=1:n_con
		if length(JuMP.name(con[jj])) == 0
	  	  con_dict[ ( con_types[kk][1],  con_types[kk][2] )  ][jj] = string(type_str_map[con_types[kk][1]],"_",type_str_map[con_types[kk][2]],"[",jj,"]")
  		  JuMP.set_name(con[jj],con_dict[ ( con_types[kk][1] ,  con_types[kk][2] ) ][jj] )
		else
	  	  con_dict[(  con_types[kk][1],  con_types[kk][2] ) ][jj]  = JuMP.name(con[jj])
		end
	    end
	end
	return con_dict
end

function Post_PF(pm::AbstractPowerModel)
    pm.setting["output"]=Dict{String,Any}("duals"=>true)
    if !haskey(pm.data,"inactive_branches")
        pm.data["inactive_branches"] = []
    end
    if !haskey(pm.data,"protected_branches")
        pm.data["protected_branches"] = []
    end
    pm.data["all_branches"] = ids(pm,pm.cnw,:branch)
    pm.data["undecided_branches"] = filter(l->!(l in pm.data["protected_branches"] || l in pm.data["inactive_branches"]), ids(pm,pm.cnw,:branch))
    if typeof(pm) in [SOCBFPowerModel, SOCBFConicPowerModel]
        build_opf_bf(pm)
    else
        build_opf(pm)
    end

    # Add new variables, modify some existing constraints and add new ones also.
    variable_branch_flow_slacks(pm)

    con(pm, pm.cnw)[:abs_pflow_fr] = Dict{Int,JuMP.ConstraintRef}()
    con(pm, pm.cnw)[:abs_pflow_to] = Dict{Int,JuMP.ConstraintRef}()
    if haskey( var(pm,pm.cnw),:q)
        con(pm, pm.cnw)[:abs_qflow_fr] = Dict{Int,JuMP.ConstraintRef}()
        con(pm, pm.cnw)[:abs_qflow_to] = Dict{Int,JuMP.ConstraintRef}()
    end

    for i in ids(pm,:bus)
	    if haskey(sol(pm, pm.cnw, :bus, i),:lam_kcl_r) && !(typeof(pm) in [NFAPowerModel])
	        pbusref=sol(pm, pm.cnw, :bus, i)[:lam_kcl_r]
            JuMP.set_name(pbusref,string("p_bal[",i,"]"))
	        for a in ref(pm,pm.cnw, :bus_arcs, i)
	            up1m = var(pm,pm.cnw, :pd_br)[a,0]
	            up1p = var(pm,pm.cnw, :pd_br)[a,1]
	            JuMP.set_normalized_coefficient(pbusref,up1m,-1)
	            JuMP.set_normalized_coefficient(pbusref,up1p,1)
	        end
	    end
	    if haskey(sol(pm, pm.cnw, :bus, i),:lam_kcl_i) && !(typeof(pm) in [DCPPowerModel,DCMPPowerModel,DCPLLPowerModel,NFAPowerModel])
	        qbusref=sol(pm, pm.cnw, :bus, i)[:lam_kcl_i]
            JuMP.set_name(qbusref,string("q_bal[",i,"]"))
	        for a in ref(pm,pm.cnw, :bus_arcs, i)
	            uq1m = var(pm,pm.cnw, :qd_br)[a,0]
	            uq1p = var(pm,pm.cnw, :qd_br)[a,1]
	            JuMP.set_normalized_coefficient(qbusref,uq1m,-1)
	            JuMP.set_normalized_coefficient(qbusref,uq1p,1)
	        end
	    end
    end
    for l in ids(pm, :branch)
        ref_p1,ref_p3,ref_q1,ref_q3 = constraint_def_abs_flow_values(pm, l)
	    if ref_p1 != nothing
            con(pm, pm.cnw)[:abs_pflow_fr][l] = ref_p1
            JuMP.set_name(ref_p1,"pi_f[$l]")
	    end
	    if ref_p3 != nothing
            con(pm, pm.cnw)[:abs_pflow_to][l] = ref_p3
            JuMP.set_name(ref_p3,"pi_t[$l]")
	    end
	    if ref_q1 != nothing
            con(pm, pm.cnw)[:abs_qflow_fr][l] = ref_q1
            JuMP.set_name(ref_q1,"phi_f[$l]")
	    end
	    if ref_q3 != nothing
            con(pm, pm.cnw)[:abs_qflow_to][l] = ref_q3
            JuMP.set_name(ref_q3,"phi_t[$l]")
	    end
    end
end

end # "end of module"


text: function f() 1

max_stars_repo_name: gabriel-doriath-dohler/pjulia

max_issues_repo_name: gabriel-doriath-dohler/pjulia

max_forks_repo_name: gabriel-doriath-dohler/pjulia


text:
using Test
using BlockSystems
using BlockSystems: @check, @checkwarn
using ModelingToolkit
using ModelingToolkit: value
using ModelingToolkit.SymbolicUtils: operation

@info "Tests of utils.jl"

@testset "utils.jl" begin
    @testset "check macro" begin
        @variables a b c d
        @check Set([a, b, c]) ⊆ Set([a,b,c,d]) "Should be subset $a"
        try
            @check Set([a, b, c]) ⊆ Set([a,b,d]) "Should be subset"
        catch e
            @test e isa ArgumentError
        end

        a = Set([1,2,3])
        b = Set([2,3,4])
        @test_logs (:warn, ) @checkwarn a ⊆ b "test"

        a = Set([1,2,3])
        b = Set([2,3,4])
        @test_logs (:warn, ) @checkwarn b ⊆ a "test"

        a = Set([1,2,3])
        b = Set([1,2,3])
        @test_logs (:warn, ) @checkwarn !(a ⊆ b) "test"

        warn = true
        @test_logs (:warn, ) @checkwarn warn length(a) == 2 "blo"
        warn = false
        @checkwarn warn length(a) == 2 "blo"

        @test_throws ArgumentError @check length(a) == 2 "blo"
    end

    @testset "remove namespace of symbols" begin
        using BlockSystems: remove_namespace
        using ModelingToolkit: renamespace, rename
        @parameters t a b(t)
        a = value(a)
        b = value(b)
        an = rename(a, renamespace(:ns, a.name))
        bn = rename(b, renamespace(:ns, operation(b).name))
        @test remove_namespace(:ns, :ns₊n) == :n
        @test remove_namespace("ns", "ns₊n") == "n"
        @test isequal(remove_namespace(:ns, an), a)
        @test isequal(remove_namespace(:ns, a), a)
        @test isequal(remove_namespace(:ns, bn), b)
        @test isequal(remove_namespace(:ns, b), b)

        @test remove_namespace(:ns₊n) == :n
        @test remove_namespace("ns₊n") == "n"
        @test remove_namespace(:ns₊ns2₊n) == :ns2₊n
        @test remove_namespace("ns₊ns2₊n") == "ns2₊n"
        @test isequal(remove_namespace(an), a)
        @test isequal(remove_namespace(a), a)
        @test isequal(remove_namespace(bn), b)
        @test isequal(remove_namespace(b), b)
    end

    @testset "eqsubstitute" begin
        using BlockSystems: eqsubstitute
        @parameters t p i(t) pn inew(t)
        @variables x(t) y xn(t) yn(t)
        D = Differential(t)
        eq = D(x) ~ x + y + p + i
        @test isequal(eqsubstitute(eq, x=>xn), D(xn) ~ xn + y + p + i)
        @test isequal(eqsubstitute(eq, y=>yn), D(x) ~ x + yn + p + i)
        @test isequal(eqsubstitute(eq, p=>pn), D(x) ~ x + y + pn + i)
        @test isequal(eqsubstitute(eq, i=>inew), D(x) ~ x + y + p + inew)
    end

    @testset "test uniquenames" begin
        using BlockSystems: uniquenames

        (t, a, b, mp) = value.(@parameters t a b(t) m)
        (x, y, mv) = value.(@variables x y(t) m)
        @test uniquenames([a, b, x, y, mp])
        @test !uniquenames([a, b, x, y, mp, mv])
    end

    @testset "equation type" begin
        using BlockSystems
        using BlockSystems: eq_type
        @parameters t
        @variables x(t) y z(t)
        D = Differential(t)

        @test eq_type(D(x) ~ 0) == (:explicit_diffeq, x.val)
        @test eq_type(D(y) ~ 0) == (:explicit_diffeq, y.val)
        @test eq_type(x ~ 0) == (:explicit_algebraic, x.val)
        @test eq_type(y ~ 0) == (:explicit_algebraic, y.val)
        @test eq_type(x ~ x^2) == (:implicit_algebraic, x.val)
        @test eq_type(y ~ y^2) == (:implicit_algebraic, y.val)
        @test eq_type(y ~ x^2) == (:explicit_algebraic, y.val)
        @test eq_type(x ~ y^2) == (:explicit_algebraic, x.val)
        @test eq_type(x ~ D(z)) == (:implicit_diffeq, x.val)
        @test eq_type(y ~ D(z)) == (:implicit_diffeq, y.val)
        @test eq_type(0 ~ x + y) == (:implicit_algebraic, nothing)
    end

    @testset "recusive subsitute" begin
        using BlockSystems: recursive_substitute
        @syms a b c
        rules = Dict([a=>b+2, b=>c])
        @test isequal(recursive_substitute(a, rules), c+2)
    end
end


text:
using ITensors
using ITensorUnicodePlots
using PastaQ
using Zygote

function ising(n; h)
  H = OpSum()
  for j in 1:(n - 1)
    H -= "Z", j, "Z", j + 1
  end
  for j in 1:n
    H += h, "X", j
  end
  return H
end

n = 30
i = [Index(2, "S=1/2") for j in 1:n];

Zp = MPS(i, "Zp");
Zm = MPS(i, "Zm");

maxlinkdim(Zp) == 1 # product state

ψ = (Zp + Zm)/√2;
maxlinkdim(ψ) == 2 # entangled state

inner(Zp, Zp) ≈ 1
inner(Zp, ψ) ≈ 1/√2

j = n ÷ 2
Xj = op("X", i[j])
XjZp = apply(Xj, Zp);
st = [k == j ? "Zm" : "Zp" for k in 1:n];
XjZp = MPS(i, st);

maxlinkdim(XjZp) == 1
inner(Zp, XjZp) == 0

h = 0.5 # field
H = MPO(ising(n; h), i);
maxlinkdim(H) == 3

Zp = MPS(i, "Zp");
inner(Zp', H, Zp) ≈ -(n-1)

# Optimize
# kwargs allow for approximate arithmatic
function minimize(f, ∂f, x; nsteps, γ, kwargs...)
  for n in 1:nsteps
  x = -(x, γ * ∂f(x); kwargs...)
  println("Step = $(n), f(x) = $(f(x))")
  end
  return x
end

# Optimize energy
function E(ψ)
  ψHψ = inner(ψ', H, ψ)
  ψψ = inner(ψ, ψ)
  return ψHψ / ψψ
end
∂E(ψ) = gradient(E, ψ)[1]

ψ0 = MPS(i, "Zp");
ψ = minimize(E, ∂E, ψ0; nsteps=50, γ=0.1, cutoff=1e-5);
ψ /= norm(ψ);

Edmrg, ψdmrg = dmrg(H, ψ0; nsweeps=10, cutoff=1e-5);

inner(ψ, ψdmrg)

maxlinkdim(ψ0) == 1
maxlinkdim(ψ) == 3
maxlinkdim(ψdmrg) == 3
E(ψ0) # ≈ -29
E(ψ) # ≈ -31.0317917
E(ψdmrg) # ≈ -31.0356110

Ry_layer(θ, i) = [op("Ry", i[j]; θ=θ[j]) for j in 1:n]
CX_layer(i) = [op("CX", i[j], i[j+1]) for j in 1:2:(n-1)]

function U(θ, i; nlayers)
  n = length(i)
  Uθ = ITensor[]
  for l in 1:(nlayers-1)
    θl = θ[(1:n) .+ l*n]
    Uθ = [Uθ; Ry_layer(θl, i)]
    Uθ = [Uθ; CX_layer(i)]
  end
  return Uθ
end

# Optimize energy
ψ0 = MPS(i, "Zp");
nlayers = 6
function E(θ)
  ψθ = apply(U(θ, i; nlayers),ψ0)
  return inner(ψθ',H,ψθ)
end
∂E(θ) = gradient(E, θ)[1]

θ0 = zeros(nlayers * n);
θ = minimize(E, ∂E, θ0; nsteps=20, γ=0.1);

ψθ = apply(U(θ, i; nlayers), ψ0);
maxlinkdim(ψ0) == 1
maxlinkdim(ψθ) == 3
E(θ0) # ≈ -29
E(θ) # ≈ -31.017062

# Optimize fidelity
ψ0 = MPS(i, "Zp");
nlayers = 6
function F(θ)
  ψθ = apply(U(θ, i; nlayers),ψ0)
  return -abs2(inner(ψ,ψθ))
end
∂F(θ) = gradient(F, θ)[1]

θ0 = zeros(nlayers * n);
θ = minimize(F, ∂F, θ0; nsteps=20, γ=0.1);

maxlinkdim(ψ0) == 1
maxlinkdim(ψθ) == 2
F(θ0) # ≈ -0.556066
F(θ) # ≈ -0.989336


text:
using Test, Documenter, WebDriver
using WebDriver: StatusError
DocMeta.setdocmeta!(WebDriver, :DocTestSetup, :(using WebDriver), recursive = true)

ENV["WEBDRIVER_HOST"] = get(ENV, "WEBDRIVER_HOST", "localhost")
ENV["WEBDRIVER_PORT"] = get(ENV, "WEBDRIVER_PORT", "4444")

@testset "WebDriver" begin
    doctest(WebDriver)
end

capabilities = Capabilities("chrome")
@test isa(capabilities, Capabilities)
wd = RemoteWebDriver(
    capabilities,
    host = ENV["WEBDRIVER_HOST"],
    port = parse(Int, ENV["WEBDRIVER_PORT"]),
)
# New Session
session = Session(wd)
@test isa(session, Session)
# Delete Session
@test delete!(session) == session.id
@test_throws WDError delete!(session)
session = Session(wd)
# Status
@test status(wd)
# Get Timeouts
@test_broken timeouts(session)
# Set Timeouts
@inferred timeouts!(session, Timeouts(implicit = 50))
@inferred timeouts!(session, Timeouts())
# Navigate To
start_url = current_url(session)
@inferred navigate!(session, "http://thedemosite.co.uk/addauser.php")
# Get Current URL
@test current_url(session) == "http://thedemosite.co.uk/addauser.php"
# Back
back!(session)
@test current_url(session) == start_url
# Forward
forward!(session)
@test current_url(session) == "http://thedemosite.co.uk/addauser.php"
# Refresh
@inferred refresh!(session)
# Get Title
@test document_title(session) == "Add a user - FREE PHP code and SQL"
# Get Window Handle
@inferred window_handle(session)
# Close Window
@inferred window_close!(session)
delete!(session)
session = Session(wd)
# Switch to Window
window!(session, window_handle(session))
# Get Window Handles
@inferred window_handles(session)
# New Window
@test_broken window!(session)
# Switch to Frame
# @inferred frame!(session, window_handle(session))
# Switch to Parent Frame
@inferred parent_frame!(session)
# Get Window Rect
@inferred rect(session)
# Set Window Rect
@test_broken rect!(session, width = 600)
# Maximize Window
@inferred maximize!(session)
# Minimize Window
@test_throws StatusError minimize!(session)
# Get Active Element
@inferred active_element(session)
# Find Element
navigate!(session, "http://book.theautomatedtester.co.uk/chapter1")
selecttype = Element(session, "xpath", """//select[@id='selecttype']""")
@test isa(selecttype, Element)
# Find Elements
selecttypes = Elements(session, "xpath", """//select[@id='selecttype']""")
@test isa(selecttypes, AbstractVector{<:Element})
# Find Element From Element
t1selenium = Element(selecttype, "xpath", """//option[@value='Selenium IDE']""")
# Find Elements from Element
tsselenium = Elements(selecttype, "xpath", """//option""")
# Is Element Selected
@test_broken isselected(selecttype)
# Get Element Attribute
@test element_attr(t1selenium, "value") == "Selenium IDE"
# Get Element Property
@test element_property(t1selenium, "value") == "Selenium IDE"
# Get Element CSS Value
@test element_css(selecttype, "font-size") == "13.3333px"
# Get Element Text
@test element_text(t1selenium) == element_attr(t1selenium, "value")
# Get Element Tag Name
@test element_tag(selecttype) == "select"
# Get Element Rect
@inferred rect(selecttype)
# Is Element Enabled
@test isenabled(selecttype)
# Element Click
radiobutton = Element(session, "xpath", """//input[@id='radiobutton']""")
@test !element_property(radiobutton, "checked")
@inferred click!(radiobutton)
@test element_property(radiobutton, "checked")
# Element Clear
text_box = Element(session, "xpath", """//*[@id='html5div']""")
@test element_text(text_box) == "To be used after the AJAX section of the book"
@inferred clear!(text_box)
@test isempty(element_text(text_box))
# Element Send Keys
element_keys!(text_box, "All your base are belong to us")
@test element_text(text_box) == "All your base are belong to us"
# Get Page Source
@inferred source(session);
# Execute Script
navigate!(session, "http://book.theautomatedtester.co.uk/chapter1")
selecttype = Element(session, "xpath", """//select[@id='selecttype']""")
@test element_attr(selecttype, "value") == "Selenium IDE"
script!(session, "arguments[0].value = arguments[1];", selecttype, "Selenium Grid")
@test element_attr(selecttype, "value") == "Selenium Grid"
# Get All Cookies
navigate!(session, "http://book.theautomatedtester.co.uk/chapter8")
@test length(cookies(session)) == 1
# Get Named Cookie
second_cookie = Element(session, "xpath", "//input[@id='secondCookie']")
click!(second_cookie)
@test cookie(session, "visitorCount").name == "visitorCount"
# Add Cookie
@inferred cookie!(session, Cookie("WhoIsAwesome", "ME!"))
@test cookie(session, "WhoIsAwesome").value == "ME!"
# Delete Cookie
@inferred delete!(session, "")
@inferred cookies(session)
# Perform Actions (Untested)
navigate!(session, "http://book.theautomatedtester.co.uk/chapter4")
hoverOver = Element(session, "xpath", "//*[@id='hoverOver']")
@inferred moveto!(hoverOver)
# User Prompts
# Get alert_text Text
@inferred alert_text(session) == "on MouseOver worked"
# Dismiss alert_text
@inferred dismiss(session)
@test_throws StatusError alert_text(session)
# Accept alert_text
navigate!(session, "http://book.theautomatedtester.co.uk/chapter4")
hoverOver = Element(session, "xpath", "//*[@id='hoverOver']")
@inferred moveto!(hoverOver)
@inferred alert_text(session) == "on MouseOver worked"
@inferred accept(session)
# Click button
navigate!(session, "https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_prompt")
button = Element(session, "css selector", "body > div.trytopnav > div > button")
@inferred click!(button)
# Change frames
example_frame = Element(session, "xpath", "//*[@name='iframeResult']")
frame!(example_frame)
button = Element(session, "xpath", "/html/body/button")
@inferred click!(button)
@inferred alert_text(session)
alert_text!(session, "Nosferican")
@inferred accept(session)
my_name = Element(session, "xpath", "//*[@id='demo']")
@test @inferred element_text(my_name) == "Hello Nosferican! How are you today?"
delete!(session)


text:
using Dispersal, Statistics, Test
using Dispersal: downsample, upsample_index, downsample_index

a = Union{Missing,Float64}[missing 2.0 3.0 4.0;
                           missing 2.0 3.0 4.0;
                           1.0 2.0 3.0 missing;
                           1.0 2.0 3.0 6.0]
scale = 2

@test downsample(a, sum, scale) == [4.0 14.0;
                                    6.0 12.0]

@test downsample(a, mean, scale) == [2.0 3.5;
                                     1.5 4.0]

@test downsample(a, maximum, scale) == [2.0 4.0;
                                        2.0 6.0]

@test downsample(a, minimum, scale) == [2.0 3.0;
                                        1.0 3.0]

@test upsample_index((1, 1), 2) == (1, 1)
@test upsample_index((2, 1), 2) == (3, 1)
@test upsample_index((1, 4), 2) == (1, 7)
@test upsample_index((3, 4), 2) == (5, 7)
@test upsample_index((100, 97), 2) == (199, 193)

@test downsample_index((1, 1), 2) == (1, 1)
@test downsample_index((3, 1), 2) == (2, 1)
@test downsample_index((1, 7), 2) == (1, 4)
@test downsample_index((6, 8), 2) == (3, 4)
@test downsample_index((199, 193), 2) == (100, 97)

@test downsample_index(upsample_index((99,324), 2), 2) == (99,324)


text:
abstract type PointStatus end

struct Free <: PointStatus end
show(io::IO, ::Free) = print(io, "free")

struct SemiFree <: PointStatus
    eq1::Int
end
show(io::IO, sf::SemiFree) = print(io, "semifree by (", sf.eq1, ")")

struct Dependent <: PointStatus
    eq1::Int
    eq2::Int
end
Dependent(a) = Dependent(a, 0)
function show(io::IO, d::Dependent)
    print(io, "dependent by ($(d.eq1)$(iszero(d.eq2) ? "" : ", $(d.eq2)"))")
end

_update_status(::Free, ::Free) = Free()
_update_status(::Free, s::PointStatus) = s
_update_status(s::PointStatus, ::Free) = s
_update_status(s1::SemiFree, s2::SemiFree) = Dependent(s1.eq1, s2.eq1)

function _update_status(s1::PointStatus, s2::PointStatus)
    throw(ArgumentError("Cannot add statement ($(s2.eq1)) to point already defined as $s1"))
end


text:
@blueprint "github" struct GitHubRepo
    type::Reflect
    user::String # user may not be the same as user.name
    repo::Maybe{String} # if nothing use pkg name
end

@blueprint "gitlab" struct GitLabRepo
    type::Reflect
    user::String
    repo::Maybe{String} # if nothing use pkg name
end

@blueprint struct GitIgnoreFile
    patterns::Vector{String} = String[]
end

@blueprint struct GitRepo
    name::Maybe{String}
    email::Maybe{String}
    branch::Maybe{String}
    ssh::Bool = false
    suffix::String = ".jl"
    gpgsign::Bool = false
    ignore::GitIgnoreFile = GitIgnoreFile()
    repo::Maybe{Union{GitHubRepo, GitLabRepo}}
end

function compile(p::GitRepo, ctx::Context)
    project_name = ctx.kwargs.name
    project_path = ctx.kwargs.path

    LibGit2.with(LibGit2.init(project_path)) do repo
        LibGit2.with(GitConfig(repo)) do config
            foreach((:name, :email)) do k
                v = getproperty(p, k)
                v === nothing || LibGit2.set!(config, "user.$k", v)
            end
        end
        LibGit2.commit(repo, "Initial commit")

        # setup default branch
        default = LibGit2.branch(repo)
        branch = something(p.branch, default)
        if branch != default
            LibGit2.branch!(repo, branch)
            LibGit2.delete_branch(LibGit2.GitReference(repo, "refs/heads/$default"))
        end
    end
    # move to remote repo setup
    isnothing(p.repo) || compile(p.repo, ctx)
    compile(p.ignore, ctx)
    return
end

function compile(p::GitHubRepo, ctx::Context)
    project_path = ctx.kwargs.path
    url = if isnothing(p.repo)
        get_default_repo_url(p.repo, project_name, p.suffix, p.ssh)
    else
        p.repo
    end

    LibGit2.with(LibGit2.GitRepo(project_path)) do repo
        close(LibGit2.GitRemote(repo, "origin", url))
    end
    # TODO: create GitHub/GitLab repo
    return
end

function get_default_repo_url(repo::GitHubRepo, pkg::String, suffix::String, ssh::Bool)
    return if ssh
        "git@github.com:$(repo.user)/$pkg$suffix.git"
    else
        "https://github.com/$(repo.user)/$pkg$suffix"
    end
end

function compile(p::GitIgnoreFile, ctx::Context)
    ignore_list = get(ctx.state, :gitignore, String[])
    append!(ignore_list, p.patterns)
    write(joinpath(ctx.kwargs.path, ".gitignore"), join(ignore_list, "\n"))
    return
end

# function compile(p::GitCommitFiles, ctx::Context)
#     project_path = ctx.kwargs.path

#     # Special case for PkgTemplates/#211
#     if Sys.iswindows()
#         files = filter(f->startswith(f, "_git2_"), readdir(project_path))
#         foreach(f -> rm(joinpath(project_path, f)), files)
#     end

#     LibGit2.with(LibGit2.GitRepo(project_path)) do repo
#         LibGit2.add!(repo, ".")
#         LibGit2.commit(repo, p.msg)
#     end
#     return
# end


text:
using LiveServer

# Make the documentation
include("make.jl")

# Serve the documentation for development
serve(dir="build")