text:
import Distributions
using LinearAlgebra: norm
import Rotations
using StaticArrays: SVector

struct UnitVector3
    v::SVector{3,Float64}
end

Base.isapprox(a::UnitVector3, b::UnitVector3) = isapprox(a.v, b.v)

function UnitVector3(a, b, c)
    v = SVector{3,Float64}(a, b, c)
    if !isapprox(norm(v), 1.0)
        error("not a unit vector, norm was $(norm(v))")
    end
    return UnitVector3(v)
end

function Base.rand(::Type{UnitVector3})
    v = SVector{3,Float64}(randn(), randn(), randn())
    return UnitVector3(v / norm(v))
end

@inline function _to_array(x::UnitVector3)
    return Float64[x.v[1], x.v[2], x.v[3]]
end

total_area(::Type{UnitVector3}) = 4 * pi

export UnitVector3

##############################################
# uniform distribution (Haar measure on S^2) #
##############################################

struct UniformDirection3D <: Gen.Distribution{UnitVector3} end

Gen.logpdf(::UniformDirection3D, x::UnitVector3) = -log(total_area(UnitVector3))

function Gen.logpdf_grad(::UniformDirection3D, x::UnitVector3)
    error("Not implemented") # TODO implement
    return (nothing,)
end

Gen.random(::UniformDirection3D) = rand(UnitVector3)

Gen.has_output_grad(::UniformDirection3D) = false

Gen.has_argument_grads(::UniformDirection3D) = ()

(::UniformDirection3D)() = Gen.random(UniformDirection3D())

const uniform_3d_direction = UniformDirection3D()

export uniform_3d_direction

########################################
# von Mises fisher distribution on S^2 #
########################################

struct VMFDirection3D <: Gen.Distribution{UnitVector3} end

function Gen.logpdf(::VMFDirection3D, x::UnitVector3, mu::UnitVector3, k::Real)
    dist = Distributions.VonMisesFisher(_to_array(mu), k)
    return Distributions.logpdf(dist, _to_array(x))
end

function Gen.logpdf_grad(::VMFDirection3D, x::UnitVector3, mu::UnitVector3, k::Real)
    error("Not implemented") # TODO implement
    return (nothing, nothing, nothing)
end

function Gen.random(::VMFDirection3D, mu::UnitVector3, k::Real)
    v = rand(Distributions.VonMisesFisher(_to_array(mu), k))
    @assert length(v) == 3
    return UnitVector3(v[1], v[2], v[3])
end

Gen.has_output_grad(::VMFDirection3D) = false

Gen.has_argument_grads(::VMFDirection3D) = (false, false)

(::VMFDirection3D)(mu, k) = Gen.random(VMFDirection3D(), mu, k)

const vmf_3d_direction = VMFDirection3D()

export vmf_3d_direction


text:
mutable struct Demographics
    lifeSpan :: Int
    lastWorkAge :: Int
    totalMass :: Float64
end

mutable struct Endowments
    effGridV :: Vector{Float64}
    # Probability of each grid point at birth
    effProbV :: Vector{Float64}
    # Transition matrix: prob(j' | j)
    trMatrix :: Matrix{Float64}
end

mutable struct CapitalGrid
    kMin :: Float64
    kMax :: Float64
    nk :: Int
end

mutable struct Budget
    ageEfficiencyV :: Vector{Float64}
    wage :: Float64
    intRate :: Float64
    taxRate :: Float64
    retireTransfer :: Float64
    cMin :: Float64
end

mutable struct Model
    demog :: Demographics
    endow :: Endowments
    kGrid :: CapitalGrid
    budget :: Budget
    util :: AbstractUtility
    # Raw parameters
    discFactor :: Float64
end

# Solution for one period while working
# Stores policy functions
# kPrime as a function of [k, efficiency]. Hence a vector of functions `k -> k'`
mutable struct WorkerSolution
    kPrimeFctV
    cFctV
end

# One solution for each t.
mutable struct Solution
    workSpan :: Integer
    solV :: Vector{WorkerSolution}
end

# -------------

ext: jl


text:
module SolverPeeker

using JuMP
using MathOptInterface
const MOI = MathOptInterface
const MOIU = MOI.Utilities

include("lprep.jl")
include("attributes.jl")
#include("peeker.jl")
include("recognize.jl")
include("solve.jl")
include("optimize.jl")

end

max_stars_repo_name: henriean/solver-peeker

max_issues_repo_name: henriean/solver-peeker

max_forks_repo_name: henriean/solver-peeker


text:
function compute(n::Int)::Int
    for c ∈ n ÷ 3 + 1:n ÷ 2
        s = c * c - n * n + 2n * c
        if s > 0
            t = trunc(Int, √s)
            if t * t == s
                b = (n - c + t) / 2
                a = n - c - b
                return a * b * c
            end
        end
    end
end

max_stars_repo_name: Dynortice/Project-Euler

max_issues_repo_name: Dynortice/Project-Euler

max_forks_repo_name: Dynortice/Project-Euler


text:
#    Copyright (c) 2021 J.A. Duffek
#    Copyright (c) 2000 D.M. Spink
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, see <http://www.gnu.org/licenses/>.

"""
    nrbdeval(nurbs::NURBS{I,F},
             dnurbs::Union{NURBS1D{I,F}, Vector{NURBS2D{I,f}}},
             tt::Union{Vector{F}, Vector{Vector{F}}, Matrix{F}}
            ) where {I<:Integer,F<:AbstractFloat}

Evaluation of the derivative NURBS curve or surface.

# Arguments:
- `nurbs`: NURBS structure
- `dnurbs`: NURBS derivative representation of `nurbs`
- `tt`: parametric evaluation points either as `Vector{F}` or
  `Vector{Vector{F}}`

# Output:
- `pnt::Union{Matrix{F},Array{F,3}}`: Evaluated points.
- `jac::Union{Matrix{F}, Vector{Array{F,3}}}`: Evaluated first derivatives
  (Jacobian).

# Examples:
```julia
julia> pnt, jac = nrbdeval(nurbs, dnurbs, tt)
julia> pnt, jac = nrbdeval(nurbs, dnurbs, [tu,tv])
```

Determine the first derivatives a NURBS curve at 9 points for 0.0 to 1.0.
```julia
julia> tt = collect(range(0.0, 1.0, length=9));
julia> dcrv = nrbderiv(crv);
julia> pnts, jac = nrbdeval(crv, dcrv, tt)
```

# Reference
- see also: [`nrbeval`](@ref), [`nrbderiv`](@ref)
"""
function nrbdeval(nurbs::NURBS{I,F},
                  dnurbs::Union{NURBS1D{I,F}, Vector{NURBS2D{I,F}}},
                  tt::Union{Vector{F}, Vector{Vector{F}}, Matrix{F}}
                 ) where {I<:Integer,F<:AbstractFloat}

cp, cw = nrbeval(nurbs,tt,:homogeneous);
pnt = cp ./ cw;

if typeof(nurbs)<:NURBS2D
  if !(typeof(dnurbs)<:Vector{NURBS2D{I,F}}) || length(dnurbs) != 2
    throw(ArgumentError("dnurbs has to be a vector of length 2 containing " *
                        "NURBS2D data structures!"));
  end # if
  # NURBS structure represents a surface

  jac = Vector{Array{F,3}}(undef,2);

  cup, cuw = nrbeval(dnurbs[1], tt, :homogeneous);
  jac[1] = (cup .- cuw .* pnt) ./ cw;

  cvp, cvw = nrbeval(dnurbs[2], tt, :homogeneous);
  jac[2] = (cvp .- cvw .* pnt) ./ cw;

  return pnt,jac;
else
  if !(typeof(dnurbs)<:NURBS1D{I,F})
    throw(ArgumentError("dnurbs for 1D NURBS is always a NURBS1D!"));
  end # if
  # NURBS structure represents a curve

  cup, cuw = nrbeval(dnurbs, tt, :homogeneous);
  jac = (cup .- cuw .* pnt) ./ cw;

  return pnt,jac;
end # if
end # nrbdeval


text:
module RandomBooleanMatrices

using Random
using RandomNumbers.Xorshifts
using SparseArrays
using StatsBase

include("curveball.jl")

@enum matrixrandomizations curveball

"""
    randomize_matrix!(m; method = curveball)

Randomize the sparse boolean Matrix `m` while maintaining row and column sums
"""
function randomize_matrix!(m::SparseMatrixCSC{Bool, Int}, rng = Random.GLOBAL_RNG; method::matrixrandomizations = curveball)
    if method == curveball
        return _curveball!(m, rng)
    end
    error("undefined method")
end

SparseMatrixCSC{Bool, Int}

struct MatrixGenerator{R<:AbstractRNG, M}
    m::M
    method::matrixrandomizations
    rng::R
end

show(io::IO, m::MatrixGenerator{R, SparseMatrixCSC{Bool, Int}}) where R = println(io, "Boolean MatrixGenerator with size $(size(m.m)) and $(nnz(m.m)) occurrences")

"""
    matrixrandomizer(m [,rng]; method = curveball)

Create a matrix generator function that will return a random boolean matrix
every time it is called, maintaining row and column sums. Non-boolean input
matrix are interpreted as boolean, where values != 0 are `true`.

# Examples
```
m = rand(0:4, 5, 6)
rmg = matrixrandomizer(m)

random1 = rand(rmg)
random2 = rand(rmg)
``
"""
matrixrandomizer(m, rng) = error("No matrixrandomizer defined for $(typeof(m))")
matrixrandomizer(m) = error("No matrixrandomizer defined for $(typeof(m))")
matrixrandomizer(m::AbstractMatrix, rng = Xoroshiro128Plus(); method::matrixrandomizations = curveball) =
    MatrixGenerator{typeof(rng), SparseMatrixCSC{Bool, Int}}(dropzeros!(sparse(m)), method, rng)
matrixrandomizer(m::SparseMatrixCSC{Bool, Int}, rng = Xoroshiro128Plus(); method::matrixrandomizations = curveball) =
    MatrixGenerator{typeof(rng), SparseMatrixCSC{Bool, Int}}(dropzeros(m), method, rng)

Random.rand(r::MatrixGenerator{R, SparseMatrixCSC{Bool, Int}}; method::matrixrandomizations = curveball) where R = copy(randomize_matrix!(r.m, r.rng, method = r.method))
Random.rand!(r::MatrixGenerator{R, SparseMatrixCSC{Bool, Int}}; method::matrixrandomizations = curveball) where R = randomize_matrix!(r.m, r.rng, method = r.method)

export randomize_matrix!, matrixrandomizer, matrixrandomizations
export curveball

end


text:
function substep(a::Matrix{Complex128}, beta::Complex128, b::Matrix{Complex128}, result::Matrix{Complex128})
    for j=1:size(a,2), i=1:size(b,1)
        result[i,j] = a[i,j] + beta*b[i,j]
    end
end

function substep2{T}(a::Matrix{T}, beta::T, b::Matrix{T}, result::Matrix{T})
    for j=1:size(a,2)
        @simd for i=1:size(b,1)
            @inbounds result[i,j] = b[i,j]*beta + a[i,j]
        end
    end
end

n = 2^6

a = rand(Complex128,n,n)
b = rand(Complex128,n,n)
result = zeros(Complex128,n,n)
beta = Complex128(0,2)

function f1(N)
    for i=1:N
        substep(a,beta,b,result)
    end
end

function f2(N)
    for i=1:N
        substep2(a,beta,b,result)
    end
end

@time f1(100000)
@time f1(100000)

@time f2(100000)
@time f2(100000)


text:
using SchumakerSpline

x = [1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6]
y = log(x) + sqrt(x)

Spline, DerivSpline, SecondDerivSpline = schumaker(x,y)

xArray = linspace(1, 6, 100)
Spp = SecondDerivSpline(xArray)

maximum(Spp) < 2*eps()


text:
using Documenter, BinaryCommitteeMachineFBP

CIbuild = get(ENV, "CI", nothing) == "true"

makedocs(
    modules  = [BinaryCommitteeMachineFBP],
    format   = Documenter.HTML(prettyurls = CIbuild),
    sitename = "BinaryCommitteeMachineFBP.jl"
    )

deploydocs(
    repo   = "github.com/carlobaldassi/BinaryCommitteeMachineFBP.jl.git",
)


text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder, Pkg

name = "gitoxide"
# Note: upstream doesn't seem to tag new versions of `gitoxide` recently, but
# the version number comes from `Cargo.toml`.
version = v"0.11.0"

# Collection of sources required to complete build
sources = [
    GitSource("https://github.com/Byron/gitoxide",
              "fb6e4b4d36c89de56a181e5ba5ae940bd62fb076"),
]

# Bash recipe for building across all platforms
script = raw"""
cd $WORKSPACE/srcdir/gitoxide*/
if [[ "${target}" == *-apple-* ]]; then
    # Help the linker find `libclang_rt.osx.a`
    export RUSTFLAGS="-Clink-args=-L${libdir}/darwin"
fi
cargo build --release
install -Dvm 755 "target/${rust_target}/release/ein${exeext}" "${bindir}/ein${exeext}"
install -Dvm 755 "target/${rust_target}/release/gix${exeext}" "${bindir}/gix${exeext}"
install_license LICENSE-*
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = supported_platforms()
# PowerPC and 32-bit ARM not supported by sha1-asm
filter!(p -> arch(p) ∉ ("powerpc64le", "armv6l", "armv7l"), platforms)
# Rust toolchain for i686 Windows is unusable
filter!(p -> !Sys.iswindows(p) || arch(p) != "i686", platforms)

# The products that we will ensure are always built
products = [
    ExecutableProduct("ein", :ein),
    ExecutableProduct("gix", :gix),
]

# Dependencies that must be installed before this package can be built
dependencies = [
    # We need libclang_rt.osx.a for linking the program.
    BuildDependency(PackageSpec(name="LLVMCompilerRT_jll", uuid="4e17d02c-6bf5-513e-be62-445f41c75a11", version=v"12.0.0"); platforms=filter(Sys.isapple, platforms)),
]

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies;
               julia_compat="1.6", preferred_gcc_version=v"5",
               compilers=[:c, :rust], lock_microarchitecture=false)

max_stars_repo_name: cmhamel/Yggdrasil

max_issues_repo_name: cmhamel/Yggdrasil

max_forks_repo_name: cmhamel/Yggdrasil


text:
"""
# Onda Corporation
# Hydrophone Preamplifier Calibration Data
#
FILE_NAME AH-2020-20-100-1238_200929.txt
#
AMP_CAL_DATE 29-Sep-2020
AMP_MFG ONDA
AMP_MODEL AH-2020-100
AMP_SN 1238
AMP_GAIN_NOM_DB 20
AMP_BW_NOM_MHZ 100
AMP_OUTPUT_IMP_NOM_OHMS 50
AMP_INPUT_CAP_NOM_PF 7.1
AMP_INPUT_CAP_DATA_TYPE CALIBRATED
AMP_GAIN_UNCERT_DB 0.03
AMP_CAP_UNCERT_PCT 2.5
#
# Calibration Data
# Freq(MHz) Gain(dB) Phase(deg) Cap(pF)
#
DATA_FIELDS 4
DATA_FIELD FREQ_MHZ
DATA_FIELD GAIN_DB
DATA_FIELD PHASE_DEG
DATA_FIELD CAP_PF
#
# End of file header
HEADER_END 0
"""

"""
`Onda_AH2020_1238_20dB`
"""

@calibration :Onda_AH2020_1238_20dB [
    000.0500 18.82 43.83 7.08
    000.0510 18.84 42.97 7.08
    000.0520 18.86 42.16 7.08
    000.0530 18.88 41.38 7.08
    000.0540 18.90 40.64 7.08
    000.0550 18.91 39.91 7.08
    000.0560 18.93 39.22 7.08
    000.0570 18.95 38.48 7.08
    000.0580 18.96 37.79 7.08
    000.0590 18.97 37.20 7.08
    000.0600 18.99 36.66 7.08
    000.0610 19.00 36.05 7.08
    000.0620 19.01 35.44 7.08
    000.0630 19.01 34.88 7.08
    000.0640 19.03 34.40 7.08
    000.0650 19.03 33.91 7.08
    000.0660 19.04 33.41 7.08
    000.0670 19.04 32.93 7.08
    000.0680 19.04 32.48 7.08
    000.0690 19.05 32.06 7.08
    000.0700 19.05 31.67 7.08
    000.0710 19.05 31.29 7.08
    000.0720 19.06 30.92 7.08
    000.0730 19.07 30.53 7.08
    000.0740 19.08 30.14 7.08
    000.0750 19.08 29.78 7.08
    000.0760 19.09 29.44 7.08
    000.0770 19.09 29.14 7.08
    000.0780 19.10 28.84 7.08
    000.0790 19.11 28.55 7.08
    000.0800 19.11 28.27 7.08
    000.0810 19.12 27.99 7.08
    000.0820 19.12 27.72 7.08
    000.0830 19.13 27.45 7.08
    000.0840 19.14 27.18 7.08
    000.0850 19.15 26.90 7.08
    000.0860 19.16 26.67 7.08
    000.0870 19.17 26.44 7.08
    000.0880 19.18 26.24 7.08
    000.0890 19.19 26.04 7.08
    000.0900 19.20 25.81 7.08
    000.0910 19.20 25.57 7.08
    000.0920 19.22 25.31 7.08
    000.0930 19.23 25.05 7.08
    000.0940 19.24 24.85 7.08
    000.0950 19.25 24.68 7.08
    000.0960 19.26 24.49 7.08
    000.0970 19.27 24.28 7.08
    000.0980 19.28 24.06 7.08
    000.0990 19.28 23.85 7.08
    000.1000 19.28 23.64 7.08
    000.1100 19.39 21.80 7.08
    000.1200 19.46 20.11 7.08
    000.1300 19.50 18.67 7.08
    000.1400 19.54 17.37 7.08
    000.1500 19.57 16.24 7.08
    000.1600 19.60 15.24 7.08
    000.1700 19.63 14.39 7.08
    000.1800 19.65 13.57 7.08
    000.1900 19.66 12.88 7.08
    000.2000 19.68 12.25 7.08
    000.2100 19.69 11.69 7.08
    000.2200 19.69 11.15 7.08
    000.2300 19.70 10.64 7.08
    000.2400 19.72 10.26 7.08
    000.2500 19.73 9.78 7.08
    000.2600 19.73 9.41 7.08
    000.2700 19.75 9.10 7.08
    000.2800 19.75 8.80 7.08
    000.2900 19.76 8.46 7.08
    000.3000 19.76 8.18 7.08
    000.3100 19.76 7.95 7.08
    000.3200 19.77 7.63 7.08
    000.3300 19.77 7.42 7.08
    000.3400 19.78 7.23 7.08
    000.3500 19.79 6.96 7.08
    000.3600 19.78 6.78 7.08
    000.3700 19.79 6.55 7.08
    000.3800 19.80 6.39 7.08
    000.3900 19.80 6.21 7.08
    000.4000 19.80 6.10 7.08
    000.4100 19.80 5.88 7.08
    000.4200 19.81 5.77 7.08
    000.4300 19.81 5.65 7.08
    000.4400 19.81 5.48 7.08
    000.4500 19.82 5.33 7.08
    000.4600 19.82 5.19 7.08
    000.4700 19.81 5.04 7.08
    000.4800 19.82 4.96 7.08
    000.4900 19.83 4.88 7.08
    000.5000 19.83 4.76 7.08
    000.5100 19.84 4.64 7.08
    000.5200 19.84 4.54 7.08
    000.5300 19.84 4.42 7.08
    000.5400 19.84 4.28 7.08
    000.5500 19.84 4.22 7.08
    000.5600 19.84 4.12 7.08
    000.5700 19.84 4.06 7.08
    000.5800 19.85 3.98 7.08
    000.5900 19.85 3.86 7.08
    000.6000 19.85 3.71 7.08
    000.6100 19.86 3.66 7.08
    000.6200 19.86 3.63 7.08
    000.6300 19.85 3.53 7.08
    000.6400 19.86 3.47 7.08
    000.6500 19.86 3.38 7.08
    000.6600 19.87 3.26 7.08
    000.6700 19.87 3.21 7.08
    000.6800 19.87 3.16 7.08
    000.6900 19.87 3.11 7.08
    000.7000 19.88 3.03 7.08
    000.7100 19.88 2.95 7.08
    000.7200 19.88 2.91 7.08
    000.7300 19.88 2.86 7.08
    000.7400 19.88 2.80 7.08
    000.7500 19.88 2.72 7.08
    000.7600 19.89 2.63 7.08
    000.7700 19.89 2.58 7.08
    000.7800 19.89 2.54 7.08
    000.7900 19.89 2.52 7.08
    000.8000 19.89 2.46 7.08
    000.8100 19.90 2.38 7.08
    000.8200 19.90 2.33 7.08
    000.8300 19.90 2.29 7.08
    000.8400 19.90 2.21 7.08
    000.8500 19.90 2.12 7.08
    000.8600 19.91 2.08 7.08
    000.8700 19.91 2.04 7.08
    000.8800 19.91 2.02 7.08
    000.8900 19.90 2.00 7.08
    000.9000 19.91 1.94 7.08
    000.9100 19.91 1.89 7.08
    000.9200 19.91 1.83 7.08
    000.9300 19.92 1.78 7.08
    000.9400 19.92 1.74 7.08
    000.9500 19.92 1.70 7.08
    000.9600 19.92 1.65 7.08
    000.9700 19.92 1.59 7.08
    000.9800 19.92 1.54 7.08
    000.9900 19.92 1.49 7.08
    001.0000 19.92 1.44 7.08
    001.1000 19.93 1.07 7.08
    001.2000 19.94 0.69 7.08
    001.3000 19.95 0.35 7.08
    001.4000 19.96 0.05 7.08
    001.5000 19.96 -0.24 7.08
    001.6000 19.98 -0.56 7.08
    001.7000 19.98 -0.83 7.08
    001.8000 19.99 -1.13 7.08
    001.9000 19.99 -1.40 7.08
    002.0000 20.00 -1.70 7.08
    002.1000 19.99 -1.96 7.08
    002.2000 19.99 -2.22 7.08
    002.3000 19.99 -2.41 7.08
    002.4000 19.99 -2.62 7.08
    002.5000 19.99 -2.85 7.08
    002.6000 20.00 -3.06 7.09
    002.7000 19.99 -3.28 7.09
    002.8000 20.00 -3.54 7.09
    002.9000 19.99 -3.70 7.09
    003.0000 19.98 -3.89 7.09
    003.1000 19.98 -4.04 7.09
    003.2000 19.98 -4.30 7.09
    003.3000 19.97 -4.49 7.09
    003.4000 19.98 -4.72 7.09
    003.5000 19.99 -4.92 7.09
    003.6000 19.98 -5.09 7.09
    003.7000 19.98 -5.24 7.09
    003.8000 19.98 -5.52 7.09
    003.9000 19.97 -5.63 7.09
    004.0000 19.97 -5.84 7.09
    004.1000 19.97 -6.01 7.09
    004.2000 19.98 -6.19 7.09
    004.3000 19.98 -6.38 7.09
    004.4000 19.98 -6.58 7.09
    004.5000 19.97 -6.73 7.09
    004.6000 19.97 -6.86 7.09
    004.7000 19.97 -7.07 7.09
    004.8000 19.98 -7.24 7.09
    004.9000 19.97 -7.46 7.09
    005.0000 19.97 -7.62 7.09
    005.1000 19.97 -7.82 7.09
    005.2000 19.98 -7.98 7.09
    005.3000 19.98 -8.14 7.09
    005.4000 19.97 -8.32 7.09
    005.5000 19.97 -8.48 7.09
    005.6000 19.97 -8.72 7.09
    005.7000 19.97 -8.86 7.09
    005.8000 19.98 -9.00 7.09
    005.9000 19.97 -9.20 7.09
    006.0000 19.97 -9.39 7.09
    006.1000 19.97 -9.54 7.09
    006.2000 19.97 -9.71 7.09
    006.3000 19.96 -9.93 7.09
    006.4000 19.96 -10.09 7.09
    006.5000 19.97 -10.24 7.09
    006.6000 19.97 -10.39 7.09
    006.7000 19.97 -10.59 7.09
    006.8000 19.96 -10.77 7.09
    006.9000 19.96 -10.92 7.10
    007.0000 19.96 -11.10 7.10
    007.1000 19.97 -11.27 7.10
    007.2000 19.96 -11.45 7.10
    007.3000 19.96 -11.63 7.10
    007.4000 19.96 -11.80 7.10
    007.5000 19.95 -11.95 7.10
    007.6000 19.95 -12.10 7.10
    007.7000 19.95 -12.29 7.10
    007.8000 19.95 -12.47 7.10
    007.9000 19.95 -12.64 7.10
    008.0000 19.95 -12.80 7.10
    008.1000 19.95 -12.96 7.10
    008.2000 19.95 -13.14 7.10
    008.3000 19.95 -13.33 7.10
    008.4000 19.95 -13.48 7.10
    008.5000 19.94 -13.63 7.10
    008.6000 19.94 -13.77 7.10
    008.7000 19.94 -13.90 7.10
    008.8000 19.94 -14.07 7.10
    008.9000 19.94 -14.25 7.10
    009.0000 19.93 -14.44 7.10
    009.1000 19.93 -14.62 7.10
    009.2000 19.93 -14.80 7.10
    009.3000 19.93 -14.98 7.10
    009.4000 19.93 -15.14 7.10
    009.5000 19.93 -15.29 7.10
    009.6000 19.92 -15.43 7.10
    009.7000 19.92 -15.59 7.10
    009.8000 19.92 -15.74 7.10
    009.9000 19.92 -15.91 7.10
    010.0000 19.92 -16.07 7.10
    011.0000 19.89 -17.71 7.11
    012.0000 19.87 -19.30 7.11
    013.0000 19.85 -20.88 7.11
    014.0000 19.83 -22.44 7.12
    015.0000 19.81 -23.99 7.12
    016.0000 19.79 -25.44 7.12
    017.0000 19.78 -26.98 7.13
    018.0000 19.78 -28.41 7.13
    019.0000 19.77 -29.91 7.13
    020.0000 19.77 -31.37 7.14
    021.0000 19.78 -32.92 7.14
    022.0000 19.78 -34.46 7.15
    023.0000 19.78 -36.01 7.15
    024.0000 19.80 -37.62 7.16
    025.0000 19.80 -39.20 7.16
    026.0000 19.80 -40.81 7.17
    027.0000 19.80 -42.39 7.17
    028.0000 19.79 -44.07 7.18
    029.0000 19.79 -45.69 7.18
    030.0000 19.77 -47.33 7.19
    031.0000 19.76 -48.99 7.19
    032.0000 19.76 -50.60 7.20
    033.0000 19.75 -52.23 7.20
    034.0000 19.73 -53.85 7.21
    035.0000 19.71 -55.47 7.21
    036.0000 19.70 -57.10 7.22
    037.0000 19.68 -58.73 7.23
    038.0000 19.66 -60.40 7.23
    039.0000 19.64 -61.96 7.24
    040.0000 19.63 -63.62 7.25
    041.0000 19.60 -65.18 7.25
    042.0000 19.59 -66.76 7.26
    043.0000 19.57 -68.34 7.27
    044.0000 19.54 -69.94 7.27
    045.0000 19.51 -71.57 7.28
    046.0000 19.50 -73.16 7.29
    047.0000 19.48 -74.71 7.29
    048.0000 19.46 -76.29 7.30
    049.0000 19.44 -77.84 7.31
    050.0000 19.42 -79.41 7.32
    051.0000 19.39 -80.99 7.32
    052.0000 19.36 -82.56 7.33
    053.0000 19.34 -84.15 7.34
    054.0000 19.32 -85.74 7.35
    055.0000 19.30 -87.31 7.36
    056.0000 19.27 -88.85 7.36
    057.0000 19.26 -90.41 7.37
    058.0000 19.24 -91.97 7.38
    059.0000 19.21 -93.55 7.39
    060.0000 19.18 -95.07 7.40
    061.0000 19.16 -96.68 7.41
    062.0000 19.14 -98.30 7.42
    063.0000 19.12 -99.87 7.43
    064.0000 19.09 -101.42 7.44
    065.0000 19.07 -102.98 7.45
    066.0000 19.05 -104.55 7.46
    067.0000 19.02 -106.13 7.46
    068.0000 19.00 -107.71 7.47
    069.0000 18.97 -109.29 7.48
    070.0000 18.95 -110.89 7.49
    071.0000 18.92 -112.49 7.50
    072.0000 18.89 -114.08 7.52
    073.0000 18.87 -115.66 7.53
    074.0000 18.85 -117.22 7.54
    075.0000 18.82 -118.82 7.55
    076.0000 18.79 -120.42 7.56
    077.0000 18.75 -122.03 7.57
    078.0000 18.72 -123.63 7.58
    079.0000 18.69 -125.21 7.59
    080.0000 18.65 -126.79 7.60
    081.0000 18.62 -128.36 7.61
    082.0000 18.59 -129.98 7.62
    083.0000 18.57 -131.62 7.64
    084.0000 18.53 -133.19 7.65
    085.0000 18.49 -134.74 7.66
    086.0000 18.46 -136.38 7.67
    087.0000 18.43 -138.03 7.68
    088.0000 18.39 -139.64 7.70
    089.0000 18.36 -141.24 7.71
    090.0000 18.32 -142.81 7.72
    091.0000 18.28 -144.38 7.73
    092.0000 18.23 -146.00 7.75
    093.0000 18.19 -147.62 7.76
    094.0000 18.15 -149.22 7.77
    095.0000 18.11 -150.82 7.78
    096.0000 18.07 -152.43 7.80
    097.0000 18.04 -154.06 7.81
    098.0000 18.00 -155.68 7.82
    099.0000 17.95 -157.25 7.84
    100.0000 17.91 -158.82 7.85
]


text:
using CSV, DataFrames, Pathways, Statistics

function sa(str::String)
    time = @elapsed begin
        c = assembly(str)
    end
    c, time
end

df = CSV.File("data/str_sa.csv") |> DataFrame
select!(df, :string, :nLetters, :nSeqs, :SA, :nPaths, :runtime)
rename!(df, Dict(:runtime => :runtime_sa))
sort!(df, :nLetters)
filter!(r -> r.nLetters < 17, df)
df.SA .-= Int.(df.nPaths .== 0)

asa = Tuple{Int,Float64}[]
@time for (n, str) in enumerate(df.string)
    println(n, "\t", str)
    push!(asa, sa(str))
end

df.ASA = first.(asa)
df.runtime_asa = last.(asa)

δ = df.SA - df.ASA
@show extrema(δ)
@show mean(δ) std(δ)

CSV.write("data/sa_asa.csv", df)


text:
println( "env.jl sourced!" )
using Touchstone
TS = Touchstone
using Test


text:
using HDF5
using Test

@testset "extend" begin

fn = tempname()

fid = h5open(fn, "w")
g = create_group(fid, "shoe")
d = create_dataset(g, "foo", datatype(Float64), ((10, 20), (100, 200)), chunk=(1, 1))
#println("d is size current $(map(int,HDF5.get_extent_dims(d)[1])) max $(map(int,HDF5.get_extent_dims(d)[2]))")
dims, max_dims = HDF5.get_extent_dims(d)
@test dims == (UInt64(10), UInt64(20))
@test max_dims == (UInt64(100), UInt64(200))
HDF5.set_extent_dims(d, (100, 150))
dims, max_dims = HDF5.get_extent_dims(d)
@test dims == (UInt64(100), UInt64(150))
@test max_dims == (UInt64(100), UInt64(200))
d[1, 1:5] = [1.1231, 1.313, 5.123, 2.231, 4.1231]
HDF5.set_extent_dims(d, (1, 5))
@test size(d) == (1, 5)

# Indexing returns correct array dimensions
@test d[1, end] ≈ 4.1231
@test d[:, end] ≈ [4.1231]
@test d[end, :] == [1.1231, 1.313, 5.123, 2.231, 4.1231]
@test d[:, :] == [1.1231 1.313 5.123 2.231 4.1231]

# Test all integer types work
@test d[UInt8(1), UInt16(1)] == 1.1231
@test d[UInt32(1), UInt128(1)] == 1.1231
@test d[Int8(1), Int16(1)] == 1.1231
@test d[Int32(1), Int128(1)] == 1.1231

# Test ranges work with steps
@test d[1, 1:2:5] == [1.1231, 5.123, 4.1231]
@test d[1:1, 2:2:4] == [1.313 2.231]

# Test Array constructor
Array(d) == [1.1231 1.313 5.123 2.231 4.1231]

#println("d is size current $(map(int,HDF5.get_extent_dims(d)[1])) max $(map(int,HDF5.get_extent_dims(d)[2]))")
b = create_dataset(fid, "b", Int, ((1000,), (-1,)), chunk=(100,)) #-1 is equivalent to typemax(hsize_t) as far as I can tell
#println("b is size current $(map(int,HDF5.get_extent_dims(b)[1])) max $(map(int,HDF5.get_extent_dims(b)[2]))")
b[1:200] = ones(200)
dims, max_dims = HDF5.get_extent_dims(b)
@test dims == (UInt64(1000),)
@test max_dims == (HDF5.H5S_UNLIMITED % Int,)
HDF5.set_extent_dims(b, (10000,))
dims, max_dims = HDF5.get_extent_dims(b)
@test dims == (UInt64(10000),)
@test max_dims == (HDF5.H5S_UNLIMITED % Int,)
#println("b is size current $(map(int,HDF5.get_extent_dims(b)[1])) max $(map(int,HDF5.get_extent_dims(b)[2]))")
# b[:] = [1:10000] # gave error no method lastindex(HDF5.Dataset{PlainHDF5File},),
# so I defined lastindex(dset::HDF5.Dataset) = length(dset), and exported lastindex
# but that didn't fix the error, despite the lastindex function working
# d[1] produces error ERROR: Wrong number of indices supplied, should datasets support linear indexing?
b[1:10000] = [1:10000;]
#println(b[1:100])

close(fid)

fid = h5open(fn, "r")
d_again = fid["shoe/foo"]
dims, max_dims = HDF5.get_extent_dims(d_again)
@test dims == (UInt64(1), UInt64(5))
@test max_dims == (UInt64(100), UInt64(200))
@test (sum(d_again[1, 1:5]) - sum([1.1231, 1.313, 5.123, 2.231, 4.1231])) == 0
#println("d is size current $(map(int,HDF5.get_extent_dims(re_d)[1])) max $(map(int,HDF5.get_extent_dims(re_d)[2]))")
@test fid["b"][1:10000] == [1:10000;]
b_again = fid["b"]
dims, max_dims = HDF5.get_extent_dims(b_again)
@test dims == (UInt64(10000),)
@test max_dims == (HDF5.H5S_UNLIMITED % Int,)
#println("b is size current $(map(int,HDF5.get_extent_dims(b)[1])) max $(map(int,HDF5.get_extent_dims(b)[2]))")

close(fid)
rm(fn)

end # testset extend_test


text:
"""
`stairs(x, y; nargs...)` → `Plot`

Description
============

Draws a staircase plot on a new canvas.
It uses the first parameter `x`
(which should be a vector or range) to denote
the horizontal position of each point,
and the second parameter `y`
(which should also be a vector or range)
as their vertical position.
This means that the two vectors have to have the same length.

Usage
======

    stairs(x, y; style = :post, title = "", name = "", width = 40, height = 15, border = :solid, xlim = [0, 0], ylim = [0, 0], margin = 3, padding = 1, color = :blue, labels = true, canvas = BrailleCanvas, grid = true)

Arguments
==========

- **`x`** : The horizontal dimension for each point.

- **`y`** : The vertical dimension for each point.

- **`style`** : Specifies where the transition of the stair takes plays. Can be either `:pre` or `:post`

- **`title`** : Text to display on the top of the plot.

- **`name`** : Annotation of the current drawing to displayed on the right

- **`width`** : Number of characters per row that should be used for plotting.

- **`height`** : Number of rows that should be used for plotting. Not applicable to `barplot`.

- **`border`** : The style of the bounding box of the plot. Supports `:solid`, `:bold`, `:dashed`, `:dotted`, `:ascii`, and `:none`.

- **`xlim`** : Plotting range for the x coordinate. `[0, 0]` stands for automatic.

- **`ylim`** : Plotting range for the y coordinate. `[0, 0]` stands for automatic.

- **`margin`** : Number of empty characters to the left of the whole plot.

- **`padding`** : Space of the left and right of the plot between the labels and the canvas.

- **`color`** : Color of the drawing. Can be any of `:blue`, `:red`, `:yellow`

- **`labels`** : Can be used to hide the labels by setting `labels=false`.

- **`canvas`** : The type of canvas that should be used for drawing.

- **`grid`** : Can be used to hide the gridlines at the origin

Returns
========

A plot object of type `Plot{T<:Canvas}`

Author(s)
==========

- Christof Stocker (Github: https://github.com/Evizero)
- Dominique (Github: https://github.com/dpo)

Examples
=========

    julia> stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], style = :post, title = "My Staircase Plot")

                    My Staircase Plot
        ┌────────────────────────────────────────┐
      7 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⡄⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⢸⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
        │⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠧⠤⠤⠤⠤⠼│
        │⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
      1 │⣀⣀⣀⣀⣀⣸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
        └────────────────────────────────────────┘
        1                                        8

See also
=========

`Plot`, `lineplot`, `scatterplot`, `BrailleCanvas`, `BlockCanvas`, `AsciiCanvas`
"""
function stairs(
        X::AbstractVector, Y::AbstractVector;
        style::Symbol = :post,
        kw...)
    x_vex, y_vex = compute_stair_lines(X, Y, style)
    lineplot(x_vex, y_vex; kw...)
end

function stairs!(
        plot::Plot{<:Canvas}, X::AbstractVector, Y::AbstractVector;
        style::Symbol = :post,
        kw...)
    x_vex, y_vex = compute_stair_lines(X, Y, style)
    lineplot!(plot, x_vex, y_vex; kw...)
end

function compute_stair_lines(
        X::AbstractVector{<:Number},
        Y::AbstractVector{<:Number},
        style::Symbol)
    if style == :post
        x_vex = zeros(length(X) * 2 - 1)
        y_vex = zeros(length(X) * 2 - 1)
        x_vex[1] = X[1]
        y_vex[1] = Y[1]
        o = 0
        for i = 2:(length(X))
            x_vex[i + o] = X[i]
            x_vex[i + o + 1] = X[i]
            y_vex[i + o] = Y[i-1]
            y_vex[i + o + 1] = Y[i]
            o += 1
        end
        x_vex, y_vex
    elseif style == :pre
        x_vex = zeros(length(X) * 2 - 1)
        y_vex = zeros(length(X) * 2 - 1)
        x_vex[1] = X[1]
        y_vex[1] = Y[1]
        o = 0
        for i = 2:(length(X))
            x_vex[i + o] = X[i-1]
            x_vex[i + o + 1] = X[i]
            y_vex[i + o] = Y[i]
            y_vex[i + o + 1] = Y[i]
            o += 1
        end
        x_vex, y_vex
    end
end


text:
using Test, Random, Flux

@testset "FourierLayer" begin
    @testset "dimensions" begin
        # Test the proper construction
        @test size(FourierLayer(128, 64, 100, 20).Wf) == (128, 64, 51)
        @test size(FourierLayer(128, 64, 100, 20).Wl) == (64, 128)
        @test size(FourierLayer(128, 64, 100, 20).bf) == (1, 64, 51)
        @test size(FourierLayer(128, 64, 100, 20).bl) == (1, 64, 100)
    end

    # Test proper parameter assignment
    # We only use a subset of the weight tensors for training
    @testset "parameters" begin
        # Wf
        @test size(Flux.params(FourierLayer(128, 64, 100, 20))[1]) == (128, 64, 20)
        # Wl
        @test size(Flux.params(FourierLayer(128, 64, 100, 20))[2]) == (64, 128)
        # bf
        @test size(Flux.params(FourierLayer(128, 64, 100, 20))[3]) == (1, 64, 20)
        # bl
        @test size(Flux.params(FourierLayer(128, 64, 100, 20))[4]) == (1, 64, 100)
    end

    # Accept only Int as architecture parameters
    @test_throws MethodError FourierLayer(128.5, 64, 100, 20)
    @test_throws MethodError FourierLayer(128.5, 64, 100, 20, tanh)
    # Test max amount of modes
    @test_throws AssertionError FourierLayer(100, 100, 100, 60, σ)
    @test_throws AssertionError FourierLayer(100, 100, 100, 60)
end


text:
using Test, JuMP
const MOIT = MOI.Test
const MOIB = MOI.Bridges
using SumOfSquares

function _model(optimizer::MOI.AbstractOptimizer)
    MOI.empty!(optimizer)
    return direct_model(optimizer)
end

function _model(factory)
    return Model(factory)
end

#const SOSPolynomial{T, OT<:MOI.ModelLike} = MOIB.Constraint.SingleBridgeOptimizer{SumOfSquares.SOSPolynomialBridge{T}, OT}

#function _cheat_model(factory::OptimizerFactory)
#    return Model(with_optimizer(() -> SOSPolynomial{Float64}(factory())))
#end

#"""
#    @test_suite setname subsets
#
#Defines a function `setname_test(model, config, exclude)` that runs the tests
#defined in the dictionary `setname_tests` with the model `model` and config
#`config` except the tests whose dictionary key is in `exclude`. If `subsets` is
#`true` then each test runs in fact multiple tests hence the `exclude` argument
#is passed as it can also contains test to be excluded from these subsets of
#tests.
#"""
macro test_suite(setname, subsets=false)
    testname = Symbol(string(setname) * "_test")
    testdict = Symbol(string(testname) * "s")
    if subsets
        runtest = :( f(model, config, exclude) )
    else
        runtest = :( f(model, config) )
    end
    esc(:(
      function $testname(model, # could be ModelLike or an optimizer constructor
                         config::$MOI.Test.TestConfig,
                         exclude::Vector{String} = String[])
            for (name,f) in $testdict
                if name in exclude
                    continue
                end
                @testset "$name" begin
                    $runtest
                end
            end
        end
    ))
end

function test_noc(model, F, S, n)
    @test MOI.get(model, MOI.NumberOfConstraints{F, S}()) == n
    @test length(MOI.get(model, MOI.ListOfConstraintIndices{F, S}())) == n
    @test ((F, S) in MOI.get(model, MOI.ListOfConstraints())) == !iszero(n)
end

# Test deletion of bridge
function test_delete_bridge(model::Model,
                            cref::ConstraintRef{Model,
                                                MOI.ConstraintIndex{F, S}},
                            nvars::Int, nocs::Tuple;
                            last_bridge = true) where {F, S}
    @test num_variables(model) == nvars
    @test length(all_variables(model)) == nvars
    test_noc(model, F, S, 1)
    for noc in nocs
        test_noc(model, noc...)
    end
    @test is_valid(model, cref)
    delete(model, cref)
    @test_throws MOI.InvalidIndex(index(cref)) delete(model, cref)
    @test !is_valid(model, cref)
    test_noc(model, F, S, 0)
    # As the bridge has been removed, if the constraints it has created where not removed, it wouldn't be there to decrease this counter anymore
    @test num_variables(model) == nvars
    @test length(all_variables(model)) == nvars
    for noc in nocs
        test_noc(model, noc...)
    end
end

# Utilities for building the mock `optimize!` from the solution of a solver
_inner(model::MOIU.CachingOptimizer) = _inner(model.optimizer)
_inner(model::MOIB.LazyBridgeOptimizer) = model.model
_cheat_inner(model::MOI.ModelLike) = model
_cheat_inner(model::MOIB.Constraint.SingleBridgeOptimizer) = _cheat_inner(model.model)
# Variables primal values for inner bridged model
function print_value(v, atol)
    i = round(v)
    if isapprox(v, i, atol=atol)
        print(float(i))
    else
        print(v)
    end
end
function inner_variable_value(model, atol=1e-4)
    #inner = _cheat_inner(backend(model))
    inner = _inner(backend(model))
    values = MOI.get(inner, MOI.VariablePrimal(),
                     MOI.get(inner, MOI.ListOfVariableIndices()))
    println("optimize!(mock) = MOIU.mock_optimize!(mock,")
    println(JuMP.termination_status(model))
    if JuMP.primal_status(model) != MOI.NO_SOLUTION
        values = MOI.get(inner, MOI.VariablePrimal(),
                         MOI.get(inner, MOI.ListOfVariableIndices()))
        print("(MOI.FEASIBLE_POINT, [")
        for (i, v) in enumerate(values)
            if i > 1
                print(", ")
            end
            print_value(v, atol)
        end
        print("])")
    else
        print("tuple()")
    end
    println(",")
    if JuMP.dual_status(model) != MOI.NO_SOLUTION
        for (F, S) in MOI.get(inner, MOI.ListOfConstraints())
            print("($F, $S) => [")
            first = true
            for ci in MOI.get(inner, MOI.ListOfConstraintIndices{F, S}())
                if !first
                    print(", ")
                end
                first = false
                print(MOI.get(inner, MOI.ConstraintDual(), ci))
            end
            println("])")
        end
    end
    println(")")
end
# Constraint dual values for inner bridged model
function inner_inspect(model, atol=1e-4)
    inner = _inner(backend(model))
    @show MOI.get(inner, MOI.NumberOfVariables())
    for (F, S) in MOI.get(inner, MOI.ListOfConstraints())
        @show F
        @show S
        @show MOI.get(inner, MOI.NumberOfConstraints{F, S}())
        if S <: MOI.AbstractVectorSet
            for ci in MOI.get(inner, MOI.ListOfConstraintIndices{F, S}())
                set = MOI.get(inner, MOI.ConstraintSet(), ci)
                @show MOI.dimension(set)
            end
        end
    end
end


text:
##
## MOOfasa.
##
"""
    function moofasa()

MOOfasa

# Example
```jldoctest
julia> cowsay("It's the circle of life", cow=Cowsay.moofasa)
 _________________________
< It's the circle of life >
 -------------------------
       \\    ____
        \\  /    \\
          | ^__^ |
          | (oo) |______
          | (__) |      )\\/\\
           \\____/|----w |
                ||     ||

             Moofasa
```
"""
function moofasa(;eyes="oo", tongue="  ", thoughts="\\")
the_cow =
"""
       $thoughts    ____
        $thoughts  /    \\
          | ^__^ |
          | ($eyes) |______
          | (__) |      )\\/\\
           \\____/|----w |
                ||     ||

             Moofasa
"""
return the_cow
end


text:
int_rules_3_3 = @theory begin

    #= ::Subsection::Closed:: =#
    #= 3.3*u*(a+b*log(c*(d+e*x)^n))^p =#
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => (1 / ~e) * Subst(Antiderivative((~a + ~b * log(~c * (~x) ^ ~n)) ^ ~p, ~x), ~x, ~d + ~e * ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n, ~p], ~x)
    @apply_utils Antiderivative((~f + ~(g') * ~x) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => (1 / ~e) * Subst(Antiderivative(((~f * ~x) / ~d) ^ ~q * (~a + ~b * log(~c * (~x) ^ ~n)) ^ ~p, ~x), ~x, ~d + ~e * ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n, ~p, ~q], ~x) && EqQ(~e * ~f - ~d * ~g, 0)
    @apply_utils Antiderivative(log(~(c') * (~d + ~(e') * (~x) ^ ~(n'))) / ~x, ~x) => -(PolyLog(2, -(~c) * ~e * (~x) ^ ~n)) / ~n <-- FreeQ([~c, ~d, ~e, ~n], ~x) && EqQ(~c * ~d, 1)
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x))) / ~x, ~x) => (~a + ~b * log(~c * ~d)) * log(~x) + ~b * Antiderivative(log(1 + (~e * ~x) / ~d) / ~x, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && GtQ(~c * ~d, 0)
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x))) / (~(f') + ~(g') * ~x), ~x) => (1 / ~g) * Subst(Antiderivative((~a + ~b * log(1 + (~c * ~e * ~x) / ~g)) / ~x, ~x), ~x, ~f + ~g * ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (NeQ(~e * ~f - ~d * ~g, 0) && EqQ(~g + ~c * (~e * ~f - ~d * ~g), 0))
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) / (~(f') + ~(g') * ~x), ~x) => (log((~e * (~f + ~g * ~x)) / (~e * ~f - ~d * ~g)) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n))) / ~g - ((~b * ~e * ~n) / ~g) * Antiderivative(log((~e * (~f + ~g * ~x)) / (~e * ~f - ~d * ~g)) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x) && NeQ(~e * ~f - ~d * ~g, 0)
    @apply_utils Antiderivative((~(f') + ~(g') * ~x) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))), ~x) => ((~f + ~g * ~x) ^ (~q + 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n))) / (~g * (~q + 1)) - ((~b * ~e * ~n) / (~g * (~q + 1))) * Antiderivative((~f + ~g * ~x) ^ (~q + 1) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n, ~q], ~x) && (NeQ(~e * ~f - ~d * ~g, 0) && NeQ(~q, -1))
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~p / (~(f') + ~(g') * ~x), ~x) => (log((~e * (~f + ~g * ~x)) / (~e * ~f - ~d * ~g)) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p) / ~g - ((~b * ~e * ~n * ~p) / ~g) * Antiderivative((log((~e * (~f + ~g * ~x)) / (~e * ~f - ~d * ~g)) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p - 1)) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n, ~p], ~x) && (NeQ(~e * ~f - ~d * ~g, 0) && IGtQ(~p, 1))
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~p / (~(f') + ~(g') * ~x) ^ 2, ~x) => ((~d + ~e * ~x) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p) / ((~e * ~f - ~d * ~g) * (~f + ~g * ~x)) - ((~b * ~e * ~n * ~p) / (~e * ~f - ~d * ~g)) * Antiderivative((~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p - 1) / (~f + ~g * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x) && (NeQ(~e * ~f - ~d * ~g, 0) && GtQ(~p, 0))
    @apply_utils Antiderivative((~(f') + ~(g') * ~x) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~p, ~x) => ((~f + ~g * ~x) ^ (~q + 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p) / (~g * (~q + 1)) - ((~b * ~e * ~n * ~p) / (~g * (~q + 1))) * Antiderivative(((~f + ~g * ~x) ^ (~q + 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p - 1)) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n, ~q], ~x) && (NeQ(~e * ~f - ~d * ~g, 0) && (GtQ(~p, 0) && (NeQ(~q, -1) && (IntegersQ(2 * ~p, 2 * ~q) && (Not(IGtQ(~q, 0)) || EqQ(~p, 2) && NeQ(~q, 1))))))
    @apply_utils Antiderivative((~(f') + ~(g') * ~x) ^ ~(q') / (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))), ~x) => Antiderivative(ExpandIntegrand((~f + ~g * ~x) ^ ~q / (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)), ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x) && (NeQ(~e * ~f - ~d * ~g, 0) && IGtQ(~q, 0))
    @apply_utils Antiderivative((~(f') + ~(g') * ~x) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~p, ~x) => (((~d + ~e * ~x) * (~f + ~g * ~x) ^ ~q * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p + 1)) / (~b * ~e * ~n * (~p + 1)) + ((~q * (~e * ~f - ~d * ~g)) / (~b * ~e * ~n * (~p + 1))) * Antiderivative((~f + ~g * ~x) ^ (~q - 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p + 1), ~x)) - ((~q + 1) / (~b * ~n * (~p + 1))) * Antiderivative((~f + ~g * ~x) ^ ~q * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p + 1), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x) && (NeQ(~e * ~f - ~d * ~g, 0) && (LtQ(~p, -1) && GtQ(~q, 0)))
    @apply_utils Antiderivative((~(f') + ~(g') * ~x) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~p, ~x) => Antiderivative(ExpandIntegrand((~f + ~g * ~x) ^ ~q * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n, ~p], ~x) && (NeQ(~e * ~f - ~d * ~g, 0) && IGtQ(~q, 0))
    @apply_utils Antiderivative(log(~(c') / (~d + ~(e') * ~x)) / (~f + ~(g') * (~x) ^ 2), ~x) => (-(~e) / ~g) * Subst(Antiderivative(log(2 * ~d * ~x) / (1 - 2 * ~d * ~x), ~x), ~x, 1 / (~d + ~e * ~x)) <-- FreeQ([~c, ~d, ~e, ~f, ~g], ~x) && (EqQ(~c, 2 * ~d) && EqQ((~e) ^ 2 * ~f + (~d) ^ 2 * ~g, 0))
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') / (~d + ~(e') * ~x))) / (~f + ~(g') * (~x) ^ 2), ~x) => (~a + ~b * log(~c / (2 * ~d))) * Antiderivative(1 / (~f + ~g * (~x) ^ 2), ~x) + ~b * Antiderivative(log((2 * ~d) / (~d + ~e * ~x)) / (~f + ~g * (~x) ^ 2), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (EqQ((~e) ^ 2 * ~f + (~d) ^ 2 * ~g, 0) && GtQ(~c / (2 * ~d), 0))
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) / sqrt(~f + ~(g') * (~x) ^ 2), ~x) => With([u = IntHide(1 / sqrt(~f + ~g * (~x) ^ 2), ~x)], u * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) - ~b * ~e * ~n * Antiderivative(SimplifyIntegrand(u / (~d + ~e * ~x), ~x), ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x) && GtQ(~f, 0)
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) / (sqrt(~f1 + ~(g1') * ~x) * sqrt(~f2 + ~(g2') * ~x)), ~x) => With([u = IntHide(1 / sqrt(~f1 * ~f2 + ~g1 * ~g2 * (~x) ^ 2), ~x)], u * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) - ~b * ~e * ~n * Antiderivative(SimplifyIntegrand(u / (~d + ~e * ~x), ~x), ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f1, ~g1, ~f2, ~g2, ~n], ~x) && (EqQ(~f2 * ~g1 + ~f1 * ~g2, 0) && (GtQ(~f1, 0) && GtQ(~f2, 0)))
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) / sqrt(~f + ~(g') * (~x) ^ 2), ~x) => (sqrt(1 + (~g / ~f) * (~x) ^ 2) / sqrt(~f + ~g * (~x) ^ 2)) * Antiderivative((~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) / sqrt(1 + (~g / ~f) * (~x) ^ 2), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x) && Not(GtQ(~f, 0))
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) / (sqrt(~f1 + ~(g1') * ~x) * sqrt(~f2 + ~(g2') * ~x)), ~x) => (sqrt(1 + ((~g1 * ~g2) / (~f1 * ~f2)) * (~x) ^ 2) / (sqrt(~f1 + ~g1 * ~x) * sqrt(~f2 + ~g2 * ~x))) * Antiderivative((~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) / sqrt(1 + ((~g1 * ~g2) / (~f1 * ~f2)) * (~x) ^ 2), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f1, ~g1, ~f2, ~g2, ~n], ~x) && EqQ(~f2 * ~g1 + ~f1 * ~g2, 0)
    @apply_utils Antiderivative((~(f') + ~(g') * (~x) ^ ~r) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => With([k = Denominator(~r)], k * Subst(Antiderivative((~x) ^ (k - 1) * (~f + ~g * (~x) ^ (k * ~r)) ^ ~q * (~a + ~b * log(~c * (~d + ~e * (~x) ^ k) ^ ~n)) ^ ~p, ~x), ~x, (~x) ^ (1 / k))) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n, ~p, ~q], ~x) && (FractionQ(~r) && IGtQ(~p, 0))
    @apply_utils Antiderivative((~f + ~(g') * (~x) ^ ~r) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => Antiderivative(ExpandIntegrand((~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, (~f + ~g * (~x) ^ ~r) ^ ~q, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n, ~r], ~x) && (IGtQ(~p, 0) && (IntegerQ(~q) && (GtQ(~q, 0) || IntegerQ(~r) && NeQ(~r, 1))))
    @apply_utils Antiderivative(((~x) ^ ~(m') * log(~(c') * (~d + ~(e') * ~x))) / (~f + ~(g') * ~x), ~x) => Antiderivative(ExpandIntegrand(log(~c * (~d + ~e * ~x)), (~x) ^ ~m / (~f + ~g * ~x), ~x), ~x) <-- FreeQ([~c, ~d, ~e, ~f, ~g], ~x) && (EqQ(~e * ~f - ~d * ~g, 0) && (EqQ(~c * ~d, 1) && IntegerQ(~m)))
    @apply_utils Antiderivative((~(f') + ~(g') * ~x) ^ ~(q') * (~(h') + ~(i') * ~x) ^ ~(r') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => (1 / ~e) * Subst(Antiderivative(((~g * ~x) / ~e) ^ ~q * ((~e * ~h - ~d * ~i) / ~e + (~i * ~x) / ~e) ^ ~r * (~a + ~b * log(~c * (~x) ^ ~n)) ^ ~p, ~x), ~x, ~d + ~e * ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~n, ~p, ~q, ~r], ~x) && (EqQ(~e * ~f - ~d * ~g, 0) && ((IGtQ(~p, 0) || IGtQ(~r, 0)) && IntegerQ(2 * ~r)))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~f + ~(g') / ~x) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => Antiderivative((~g + ~f * ~x) ^ ~q * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~m, ~n, ~p, ~q], ~x) && (EqQ(~m, ~q) && IntegerQ(~q))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~(f') + ~(g') * (~x) ^ ~(r')) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => ((~f + ~g * (~x) ^ ~r) ^ (~q + 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p) / (~g * ~r * (~q + 1)) - ((~b * ~e * ~n * ~p) / (~g * ~r * (~q + 1))) * Antiderivative(((~f + ~g * (~x) ^ ~r) ^ (~q + 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p - 1)) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~m, ~n, ~q, ~r], ~x) && (EqQ(~m, ~r - 1) && (NeQ(~q, -1) && IGtQ(~p, 0)))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~f + ~(g') * (~x) ^ ~(r')) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))), ~x) => With([u = IntHide((~x) ^ ~m * (~f + ~g * (~x) ^ ~r) ^ ~q, ~x)], Dist(~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n), u, ~x) - ~b * ~e * ~n * Antiderivative(SimplifyIntegrand(u / (~d + ~e * ~x), ~x), ~x) <-- InverseFunctionFreeQ(u, ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~m, ~n, ~q, ~r], ~x) && (IntegerQ(~m) && (IntegerQ(~q) && IntegerQ(~r)))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~(f') + ~(g') * (~x) ^ ~r) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => With([k = Denominator(~r)], k * Subst(Antiderivative((~x) ^ (k * (~m + 1) - 1) * (~f + ~g * (~x) ^ (k * ~r)) ^ ~q * (~a + ~b * log(~c * (~d + ~e * (~x) ^ k) ^ ~n)) ^ ~p, ~x), ~x, (~x) ^ (1 / k))) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n, ~p, ~q], ~x) && (FractionQ(~r) && (IGtQ(~p, 0) && IntegerQ(~m)))
    @apply_utils Antiderivative((~(h') * ~x) ^ ~(m') * (~f + ~(g') * (~x) ^ ~(r')) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => Antiderivative(ExpandIntegrand((~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, (~h * ~x) ^ ~m * (~f + ~g * (~x) ^ ~r) ^ ~q, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~m, ~n, ~p, ~q, ~r], ~x) && (IntegerQ(~m) && IntegerQ(~q))
    @apply_utils Antiderivative(~Polyx * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => Antiderivative(ExpandIntegrand(~Polyx * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n, ~p], ~x) && PolynomialQ(~Polyx, ~x)
    @apply_utils Antiderivative(~RFx * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => With([u = ExpandIntegrand((~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~RFx, ~x)], Antiderivative(u, ~x) <-- SumQ(u)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n], ~x) && (RationalFunctionQ(~RFx, ~x) && IntegerQ(~p))
    @apply_utils Antiderivative(~RFx * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => With([u = ExpandIntegrand(~RFx * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~x)], Antiderivative(u, ~x) <-- SumQ(u)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n], ~x) && (RationalFunctionQ(~RFx, ~x) && IntegerQ(~p))
    @apply_utils Antiderivative(~AFx * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => Unintegrable(~AFx * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n, ~p], ~x) && AlgebraicFunctionQ(~AFx, ~x, True)
    @apply_utils Antiderivative((~u) ^ ~(q') * (~(a') + ~(b') * log(~(c') * (~v) ^ ~(n'))) ^ ~(p'), ~x) => Antiderivative(ExpandToSum(~u, ~x) ^ ~q * (~a + ~b * log(~c * ExpandToSum(~v, ~x) ^ ~n)) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~n, ~p, ~q], ~x) && (BinomialQ(~u, ~x) && (LinearQ(~v, ~x) && Not(BinomialMatchQ(~u, ~x) && LinearMatchQ(~v, ~x))))
    @apply_utils Antiderivative(log(~(f') * (~x) ^ ~(m')) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))), ~x) => (-(~x) * (~m - log(~f * (~x) ^ ~m)) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) + ~b * ~e * ~m * ~n * Antiderivative(~x / (~d + ~e * ~x), ~x)) - ~b * ~e * ~n * Antiderivative((~x * log(~f * (~x) ^ ~m)) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~m, ~n], ~x)
    @apply_utils Antiderivative(log(~(f') * (~x) ^ ~(m')) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~p, ~x) => With([u = IntHide((~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~x)], Dist(log(~f * (~x) ^ ~m), u, ~x) - ~m * Antiderivative(Dist(1 / ~x, u, ~x), ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~m, ~n], ~x) && IGtQ(~p, 1)
    @apply_utils Antiderivative(log(~(f') * (~x) ^ ~(m')) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => Unintegrable(log(~f * (~x) ^ ~m) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~m, ~n, ~p], ~x)
    @apply_utils Antiderivative((log(~(f') * (~x) ^ ~(m')) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n')))) / ~x, ~x) => (log(~f * (~x) ^ ~m) ^ 2 * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n))) / (2 * ~m) - ((~b * ~e * ~n) / (2 * ~m)) * Antiderivative(log(~f * (~x) ^ ~m) ^ 2 / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~m, ~n], ~x)
    @apply_utils Antiderivative((~(g') * ~x) ^ ~(q') * log(~(f') * (~x) ^ ~(m')) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))), ~x) => ((-1 / (~g * (~q + 1))) * ((~m * (~g * ~x) ^ (~q + 1)) / (~q + 1) - (~g * ~x) ^ (~q + 1) * log(~f * (~x) ^ ~m)) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) + ((~b * ~e * ~m * ~n) / (~g * (~q + 1) ^ 2)) * Antiderivative((~g * ~x) ^ (~q + 1) / (~d + ~e * ~x), ~x)) - ((~b * ~e * ~n) / (~g * (~q + 1))) * Antiderivative(((~g * ~x) ^ (~q + 1) * log(~f * (~x) ^ ~m)) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~m, ~n, ~q], ~x) && NeQ(~q, -1)
    @apply_utils Antiderivative((log(~(f') * (~x) ^ ~(m')) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p')) / ~x, ~x) => (log(~f * (~x) ^ ~m) ^ 2 * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p) / (2 * ~m) - ((~b * ~e * ~n * ~p) / (2 * ~m)) * Antiderivative((log(~f * (~x) ^ ~m) ^ 2 * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p - 1)) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~m, ~n], ~x) && IGtQ(~p, 0)
    @apply_utils Antiderivative((~(g') * ~x) ^ ~(q') * log(~(f') * (~x) ^ ~(m')) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~p, ~x) => With([u = IntHide((~g * ~x) ^ ~q * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~x)], Dist(log(~f * (~x) ^ ~m), u, ~x) - ~m * Antiderivative(Dist(1 / ~x, u, ~x), ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~m, ~n, ~q], ~x) && (IGtQ(~p, 1) && IGtQ(~q, 0))
    #= Antiderivative(((~g')*(~x))^(~q')*log((~f')*(~x)^(~m'))*((~a')+(~b')*log((~c')*((~d)+(~e')*(~x))^(~n'))) ^(~p),~x) := With([u=IntHide((a+b*log(c*(d+e*x)^n))^p,x)], Dist((g*x)^q*log(f*x^m),u,x) - g*m*Antiderivative(Dist((g*x)^(q-1),u,x),x) -  g*q*Antiderivative(Dist((g*x)^(q-1)*log(f*x^m),u,x),x)) <--  FreeQ([a,b,c,d,e,f,g,m,n,q],x) && IGtQ(p,1) =#
    @apply_utils Antiderivative((~(g') * ~x) ^ ~(q') * log(~(f') * (~x) ^ ~(m')) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => Unintegrable((~g * ~x) ^ ~q * log(~f * (~x) ^ ~m) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~m, ~n, ~p, ~q], ~x)
    @apply_utils Antiderivative(log(~(f') * (~(g') + ~(h') * ~x) ^ ~(m')) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p'), ~x) => (1 / ~e) * Subst(Antiderivative(log(~f * ((~g * ~x) / ~d) ^ ~m) * (~a + ~b * log(~c * (~x) ^ ~n)) ^ ~p, ~x), ~x, ~d + ~e * ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~m, ~n, ~p], ~x) && EqQ(~e * ~f - ~d * ~g, 0)
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) * (~(f') + ~(g') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))), ~x) => ~x * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) * (~f + ~g * log(~c * (~d + ~e * ~x) ^ ~n)) - ~e * ~n * Antiderivative((~x * (~b * ~f + ~a * ~g + 2 * ~b * ~g * log(~c * (~d + ~e * ~x) ^ ~n))) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x)
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p') * (~(f') + ~(g') * log(~(h') * (~(i') + ~(j') * ~x) ^ ~(m'))), ~x) => (~x * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p * (~f + ~g * log(~h * (~i + ~j * ~x) ^ ~m)) - ~g * ~j * ~m * Antiderivative((~x * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p) / (~i + ~j * ~x), ~x)) - ~b * ~e * ~n * ~p * Antiderivative((~x * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p - 1) * (~f + ~g * log(~h * (~i + ~j * ~x) ^ ~m))) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~j, ~m, ~n], ~x) && IGtQ(~p, 0)
    @apply_utils Antiderivative((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p') * (~(f') + ~(g') * log(~(h') * (~(i') + ~(j') * ~x) ^ ~(m'))) ^ ~(q'), ~x) => Unintegrable((~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p * (~f + ~g * log(~h * (~i + ~j * ~x) ^ ~m)) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~j, ~m, ~n, ~p], ~x)
    @apply_utils Antiderivative((~(k') + ~(l') * ~x) ^ ~(r') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p') * (~(f') + ~(g') * log(~(h') * (~(i') + ~(j') * ~x) ^ ~(m'))), ~x) => (1 / ~e) * Subst(Antiderivative(((~k * ~x) / ~d) ^ ~r * (~a + ~b * log(~c * (~x) ^ ~n)) ^ ~p * (~f + ~g * log(~h * ((~e * ~i - ~d * ~j) / ~e + (~j * ~x) / ~e) ^ ~m)), ~x), ~x, ~d + ~e * ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~j, ~k, ~l, ~n, ~p, ~r], ~x) && EqQ(~e * ~k - ~d * ~l, 0)
    @apply_utils Antiderivative(((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) * (~(f') + ~(g') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n')))) / ~x, ~x) => log(~x) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) * (~f + ~g * log(~c * (~d + ~e * ~x) ^ ~n)) - ~e * ~n * Antiderivative((log(~x) * (~b * ~f + ~a * ~g + 2 * ~b * ~g * log(~c * (~d + ~e * ~x) ^ ~n))) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x)
    @apply_utils Antiderivative((~x) ^ ~(m') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) * (~(f') + ~(g') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))), ~x) => ((~x) ^ (~m + 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) * (~f + ~g * log(~c * (~d + ~e * ~x) ^ ~n))) / (~m + 1) - ((~e * ~n) / (~m + 1)) * Antiderivative(((~x) ^ (~m + 1) * (~b * ~f + ~a * ~g + 2 * ~b * ~g * log(~c * (~d + ~e * ~x) ^ ~n))) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n, ~m], ~x) && NeQ(~m, -1)
    @apply_utils Antiderivative(((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) * (~(f') + ~(g') * log(~(h') * (~(i') + ~(j') * ~x) ^ ~(m')))) / ~x, ~x) => (log(~x) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) * (~f + ~g * log(~h * (~i + ~j * ~x) ^ ~m)) - ~e * ~g * ~m * Antiderivative((log(~x) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n))) / (~d + ~e * ~x), ~x)) - ~b * ~j * ~n * Antiderivative((log(~x) * (~f + ~g * log(~h * (~i + ~j * ~x) ^ ~m))) / (~i + ~j * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~j, ~m, ~n], ~x) && EqQ(~e * ~i - ~d * ~j, 0)
    @apply_utils Antiderivative((log(~a + ~(b') * ~x) * log(~c + ~(d') * ~x)) / ~x, ~x) => (((((((log((-(~b) * ~x) / ~a) * log(~a + ~b * ~x) * log(~c + ~d * ~x) - (1 / 2) * (log((-(~b) * ~x) / ~a) - log((-(~d) * ~x) / ~c)) * (log(~a + ~b * ~x) + log((~a * (~c + ~d * ~x)) / (~c * (~a + ~b * ~x)))) ^ 2) + (1 / 2) * ((log((-(~b) * ~x) / ~a) - log((-((~b * ~c - ~a * ~d)) * ~x) / (~a * (~c + ~d * ~x)))) + log((~b * ~c - ~a * ~d) / (~b * (~c + ~d * ~x)))) * log((~a * (~c + ~d * ~x)) / (~c * (~a + ~b * ~x))) ^ 2 + (log(~c + ~d * ~x) - log((~a * (~c + ~d * ~x)) / (~c * (~a + ~b * ~x)))) * PolyLog(2, 1 + (~b * ~x) / ~a) + (log(~a + ~b * ~x) + log((~a * (~c + ~d * ~x)) / (~c * (~a + ~b * ~x)))) * PolyLog(2, 1 + (~d * ~x) / ~c)) - log((~a * (~c + ~d * ~x)) / (~c * (~a + ~b * ~x))) * PolyLog(2, (~d * (~a + ~b * ~x)) / (~b * (~c + ~d * ~x)))) + log((~a * (~c + ~d * ~x)) / (~c * (~a + ~b * ~x))) * PolyLog(2, (~c * (~a + ~b * ~x)) / (~a * (~c + ~d * ~x)))) - PolyLog(3, 1 + (~b * ~x) / ~a)) - PolyLog(3, 1 + (~d * ~x) / ~c)) - PolyLog(3, (~d * (~a + ~b * ~x)) / (~b * (~c + ~d * ~x)))) + PolyLog(3, (~c * (~a + ~b * ~x)) / (~a * (~c + ~d * ~x))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && NeQ(~b * ~c - ~a * ~d, 0)
    @apply_utils Antiderivative((log(~v) * log(~w)) / ~x, ~x) => Antiderivative((log(ExpandToSum(~v, ~x)) * log(ExpandToSum(~w, ~x))) / ~x, ~x) <-- LinearQ([~v, ~w], ~x) && Not(LinearMatchQ([~v, ~w], ~x))
    @apply_utils Antiderivative((log(~(c') * (~d + ~(e') * ~x) ^ ~(n')) * log(~(h') * (~(i') + ~(j') * ~x) ^ ~(m'))) / ~x, ~x) => ~m * Antiderivative((log(~i + ~j * ~x) * log(~c * (~d + ~e * ~x) ^ ~n)) / ~x, ~x) - (~m * log(~i + ~j * ~x) - log(~h * (~i + ~j * ~x) ^ ~m)) * Antiderivative(log(~c * (~d + ~e * ~x) ^ ~n) / ~x, ~x) <-- FreeQ([~c, ~d, ~e, ~h, ~i, ~j, ~m, ~n], ~x) && (NeQ(~e * ~i - ~d * ~j, 0) && NeQ(~i + ~j * ~x, ~h * (~i + ~j * ~x) ^ ~m))
    @apply_utils Antiderivative(((~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) * (~f + ~(g') * log(~(h') * (~(i') + ~(j') * ~x) ^ ~(m')))) / ~x, ~x) => ~f * Antiderivative((~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) / ~x, ~x) + ~g * Antiderivative((log(~h * (~i + ~j * ~x) ^ ~m) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n))) / ~x, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~j, ~m, ~n], ~x) && NeQ(~e * ~i - ~d * ~j, 0)
    @apply_utils Antiderivative((~x) ^ ~(r') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p') * (~(f') + ~(g') * log(~(h') * (~(i') + ~(j') * ~x) ^ ~(m'))), ~x) => (((~x) ^ (~r + 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p * (~f + ~g * log(~h * (~i + ~j * ~x) ^ ~m))) / (~r + 1) - ((~g * ~j * ~m) / (~r + 1)) * Antiderivative(((~x) ^ (~r + 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p) / (~i + ~j * ~x), ~x)) - ((~b * ~e * ~n * ~p) / (~r + 1)) * Antiderivative(((~x) ^ (~r + 1) * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ (~p - 1) * (~f + ~g * log(~h * (~i + ~j * ~x) ^ ~m))) / (~d + ~e * ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~j, ~m, ~n], ~x) && (IGtQ(~p, 0) && (IntegerQ(~r) && ((EqQ(~p, 1) || GtQ(~r, 0)) && NeQ(~r, -1))))
    @apply_utils Antiderivative((~k + ~(l') * ~x) ^ ~(r') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) * (~(f') + ~(g') * log(~(h') * (~(i') + ~(j') * ~x) ^ ~(m'))), ~x) => (1 / ~l) * Subst(Antiderivative((~x) ^ ~r * (~a + ~b * log(~c * (-((~e * ~k - ~d * ~l)) / ~l + (~e * ~x) / ~l) ^ ~n)) * (~f + ~g * log(~h * (-((~j * ~k - ~i * ~l)) / ~l + (~j * ~x) / ~l) ^ ~m)), ~x), ~x, ~k + ~l * ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~j, ~k, ~l, ~m, ~n], ~x) && IntegerQ(~r)
    @apply_utils Antiderivative((~(k') + ~(l') * ~x) ^ ~(r') * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p') * (~(f') + ~(g') * log(~(h') * (~(i') + ~(j') * ~x) ^ ~(m'))) ^ ~(q'), ~x) => Unintegrable((~k + ~l * ~x) ^ ~r * (~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n)) ^ ~p * (~f + ~g * log(~h * (~i + ~j * ~x) ^ ~m)) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~j, ~k, ~l, ~m, ~n, ~p, ~q, ~r], ~x)
    @apply_utils Antiderivative((PolyLog(~k, ~h + ~(i') * ~x) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))) ^ ~(p')) / (~f + ~(g') * ~x), ~x) => (1 / ~g) * Subst(Antiderivative((PolyLog(~k, (~h * ~x) / ~d) * (~a + ~b * log(~c * (~x) ^ ~n)) ^ ~p) / ~x, ~x), ~x, ~d + ~e * ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i, ~k, ~n], ~x) && (EqQ(~e * ~f - ~d * ~g, 0) && (EqQ(~g * ~h - ~f * ~i, 0) && IGtQ(~p, 0)))
    @apply_utils Antiderivative(~(Px') * (~F)(~(f') * (~(g') + ~(h') * ~x)) * (~(a') + ~(b') * log(~(c') * (~d + ~(e') * ~x) ^ ~(n'))), ~x) => With([u = IntHide(~Px * (~F)(~f * (~g + ~h * ~x)), ~x)], Dist(~a + ~b * log(~c * (~d + ~e * ~x) ^ ~n), u, ~x) - ~b * ~e * ~n * Antiderivative(SimplifyIntegrand(u / (~d + ~e * ~x), ~x), ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~n], ~x) && (PolynomialQ(~Px, ~x) && MemberQ([asin, acos, atan, acot, asinh, acosh, atanh, acoth], ~F))
    @apply_utils Antiderivative(~(u') * (~(a') + ~(b') * log(~(c') * (~v) ^ ~(n'))) ^ ~(p'), ~x) => Antiderivative(~u * (~a + ~b * log(~c * ExpandToSum(~v, ~x) ^ ~n)) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~n, ~p], ~x) && (LinearQ(~v, ~x) && (Not(LinearMatchQ(~v, ~x)) && Not(EqQ(~n, 1) && MatchQ(~c * ~v, ~(e') * (~f + ~(g') * ~x) <-- FreeQ([e, f, g], ~x)))))
    @apply_utils Antiderivative(~(u') * (~(a') + ~(b') * log(~(c') * (~(d') * (~(e') + ~(f') * ~x) ^ ~(m')) ^ ~n)) ^ ~(p'), ~x) => Subst(Antiderivative(~u * (~a + ~b * log(~c * (~d) ^ ~n * (~e + ~f * ~x) ^ (~m * ~n))) ^ ~p, ~x), ~c * (~d) ^ ~n * (~e + ~f * ~x) ^ (~m * ~n), ~c * (~d * (~e + ~f * ~x) ^ ~m) ^ ~n) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~m, ~n, ~p], ~x) && (Not(IntegerQ(~n)) && (Not(EqQ(~d, 1) && EqQ(~m, 1)) && IntegralFreeQ(IntHide(~u * (~a + ~b * log(~c * (~d) ^ ~n * (~e + ~f * ~x) ^ (~m * ~n))) ^ ~p, ~x))))
    @apply_utils Antiderivative(~AFx * (~(a') + ~(b') * log(~(c') * (~(d') * (~(e') + ~(f') * ~x) ^ ~(m')) ^ ~n)) ^ ~(p'), ~x) => Unintegrable(~AFx * (~a + ~b * log(~c * (~d * (~e + ~f * ~x) ^ ~m) ^ ~n)) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~m, ~n, ~p], ~x) && AlgebraicFunctionQ(~AFx, ~x, True)
end

max_stars_repo_path: src/rules/3 Logarithms/3.3 u (a+b log(c (d+e x)^n))^p.jl


text:
module Docs
    using YAML, HTTP, Markdown, Printf

    export releaseVersion, releaseVector, markdownTemplate, redocTemplate

    redocTpl = raw"""
<!DOCTYPE html>
<html>
<head>
    <title>%s</title>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">

    <style>
    body {
        margin: 0;
        padding: 0;
    }
    </style>
</head>
<body>
    <redoc spec-url='%s'></redoc>
    <script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script>
</body>
</html>
"""

    releaseVersion() = get(ENV, "RELEASE_VERSION", "master")
    releaseVector() = release_vector

    r = HTTP.request("GET", string("https://raw.githubusercontent.com/metal-stack/releases/", releaseVersion(), "/release.yaml"))
    release_vector = YAML.load(String(r.body))

    constsprintf(fmt::String, args...) = @eval @sprintf($fmt, $(args...))

    function markdownTemplate(t, x...)
        return Markdown.parse(constsprintf(t, x...))
    end

    function redocTemplate(name, url)
        return constsprintf(redocTpl, name, url)
    end
end

max_stars_repo_name: metal-stack/docs

max_issues_repo_name: metal-stack/docs

max_forks_repo_name: metal-stack/docs


text:
using SugarBLAS
using Base.Test

#scale!
@test macroexpand(:(@scale! X *= a)) == :(scale!(a, X))
@test macroexpand(:(@scale! X = a*X)) == :(scale!(a, X))
@test macroexpand(:(@blas! X *= a)) == :(scale!(a, X))
@test macroexpand(:(@blas! X = a*X)) == :(scale!(a, X))

#axpy!
@test macroexpand(:(@axpy! Y -= a*X)) == :(Base.LinAlg.axpy!(-a, X, Y))
@test macroexpand(:(@axpy! Y = Y - a*X)) == :(Base.LinAlg.axpy!(-a, X, Y))
@test macroexpand(:(@axpy! Y = Y - X)) == :(Base.LinAlg.axpy!(-1.0, X, Y))
@test macroexpand(:(@axpy! Y -= X)) == :(Base.LinAlg.axpy!(-1.0, X, Y))
@test macroexpand(:(@axpy! Y += a*X)) == :(Base.LinAlg.axpy!(a, X, Y))
@test macroexpand(:(@axpy! Y = a*X + Y)) == :(Base.LinAlg.axpy!(a, X, Y))
@test macroexpand(:(@axpy! Y = Y + a*X)) == :(Base.LinAlg.axpy!(a, X, Y))
@test macroexpand(:(@axpy! Y = X + Y)) == :(Base.LinAlg.axpy!(1.0, X, Y))
@test macroexpand(:(@axpy! Y = Y + X)) == :(Base.LinAlg.axpy!(1.0, X, Y))
@test macroexpand(:(@axpy! Y += X)) == :(Base.LinAlg.axpy!(1.0, X, Y))
@test macroexpand(:(@blas! Y -= a*X)) == :(Base.LinAlg.axpy!(-a, X, Y))
@test macroexpand(:(@blas! Y = Y - a*X)) == :(Base.LinAlg.axpy!(-a, X, Y))
@test macroexpand(:(@blas! Y = Y - X)) == :(Base.LinAlg.axpy!(-1.0, X, Y))
@test macroexpand(:(@blas! Y -= X)) == :(Base.LinAlg.axpy!(-1.0, X, Y))
@test macroexpand(:(@blas! Y += a*X)) == :(Base.LinAlg.axpy!(a, X, Y))
@test macroexpand(:(@blas! Y = a*X + Y)) == :(Base.LinAlg.axpy!(a, X, Y))
@test macroexpand(:(@blas! Y = Y + a*X)) == :(Base.LinAlg.axpy!(a, X, Y))
@test macroexpand(:(@blas! Y = X + Y)) == :(Base.LinAlg.axpy!(1.0, X, Y))
@test macroexpand(:(@blas! Y = Y + X)) == :(Base.LinAlg.axpy!(1.0, X, Y))
@test macroexpand(:(@blas! Y += X)) == :(Base.LinAlg.axpy!(1.0, X, Y))

#copy!
@test macroexpand(:(@copy! X = Y)) == :(copy!(X, Y))
@test macroexpand(:(@blas! X = Y)) == :(copy!(X, Y))

#ger!
@test macroexpand(:(@ger! A -= alpha*x*y')) == :(Base.LinAlg.BLAS.ger!(-alpha,x,y,A))
@test macroexpand(:(@ger! A = A - alpha*x*y')) == :(Base.LinAlg.BLAS.ger!(-alpha,x,y,A))
@test macroexpand(:(@ger! A += alpha*x*y')) == :(Base.LinAlg.BLAS.ger!(alpha,x,y,A))
@test macroexpand(:(@ger! A = alpha*x*y' + A)) == :(Base.LinAlg.BLAS.ger!(alpha,x,y,A))

#syr!
@test macroexpand(:(@syr! A[:U] -= alpha*x*x.')) == :(Base.LinAlg.BLAS.syr!('U',-alpha,x,A))
@test macroexpand(:(@syr! A[:L] -= alpha*x*x.')) == :(Base.LinAlg.BLAS.syr!('L',-alpha,x,A))
@test macroexpand(:(@syr! A[:U] = A - alpha*x*x.')) == :(Base.LinAlg.BLAS.syr!('U',-alpha,x,A))
@test macroexpand(:(@syr! A[:L] = A - alpha*x*x.')) == :(Base.LinAlg.BLAS.syr!('L',-alpha,x,A))
@test macroexpand(:(@syr! A[:U] += alpha*x*x.')) == :(Base.LinAlg.BLAS.syr!('U',alpha,x,A))
@test macroexpand(:(@syr! A[:L] += alpha*x*x.')) == :(Base.LinAlg.BLAS.syr!('L',alpha,x,A))
@test macroexpand(:(@syr! A[:U] = alpha*x*x.' + A)) == :(Base.LinAlg.BLAS.syr!('U',alpha,x,A))
@test macroexpand(:(@syr! A[:L] = alpha*x*x.' + A)) == :(Base.LinAlg.BLAS.syr!('L',alpha,x,A))

#syrk!
@test macroexpand(:(@syrk! C[:U] -= alpha*A*A.')) == :(Base.LinAlg.BLAS.syrk!('U','N',-alpha,A,1.0,C))
@test macroexpand(:(@syrk! C[:U] -= alpha*A.'*A)) == :(Base.LinAlg.BLAS.syrk!('U','T',-alpha,A,1.0,C))
@test macroexpand(:(@syrk! C[:U] = C - alpha*A*A.')) == :(Base.LinAlg.BLAS.syrk!('U','N',-alpha,A,1.0,C))
@test macroexpand(:(@syrk! C[:U] = C - alpha*A.'*A)) == :(Base.LinAlg.BLAS.syrk!('U','T',-alpha,A,1.0,C))
@test macroexpand(:(@syrk! C[:U] = beta*C - alpha*A*A.')) == :(Base.LinAlg.BLAS.syrk!('U','N',-alpha,A,beta,C))
@test macroexpand(:(@syrk! C[:L] = beta*C - alpha*A.'*A)) == :(Base.LinAlg.BLAS.syrk!('L','T',-alpha,A,beta,C))
@test macroexpand(:(@syrk! C[:U] += alpha*A*A.')) == :(Base.LinAlg.BLAS.syrk!('U','N',alpha,A,1.0,C))
@test macroexpand(:(@syrk! C[:U] += alpha*A.'*A)) == :(Base.LinAlg.BLAS.syrk!('U','T',alpha,A,1.0,C))
@test macroexpand(:(@syrk! C[:U] = alpha*A*A.' + C)) == :(Base.LinAlg.BLAS.syrk!('U','N',alpha,A,1.0,C))
@test macroexpand(:(@syrk! C[:U] = C + alpha*A.'*A)) == :(Base.LinAlg.BLAS.syrk!('U','T',alpha,A,1.0,C))
@test macroexpand(:(@syrk! C[:U] = alpha*A*A.' + beta*C)) == :(Base.LinAlg.BLAS.syrk!('U','N',alpha,A,beta,C))
@test macroexpand(:(@syrk! C[:L] = alpha*A.'*A + beta*C)) == :(Base.LinAlg.BLAS.syrk!('L','T',alpha,A,beta,C))

#her!
@test macroexpand(:(@her! A[:U] -= alpha*x*x')) == :(Base.LinAlg.BLAS.her!('U',-alpha,x,A))
@test macroexpand(:(@her! A[:L] -= alpha*x*x')) == :(Base.LinAlg.BLAS.her!('L',-alpha,x,A))
@test macroexpand(:(@her! A[:U] = A - alpha*x*x')) == :(Base.LinAlg.BLAS.her!('U',-alpha,x,A))
@test macroexpand(:(@her! A[:L] = A - alpha*x*x')) == :(Base.LinAlg.BLAS.her!('L',-alpha,x,A))
@test macroexpand(:(@her! A[:U] = alpha*x*x' + A)) == :(Base.LinAlg.BLAS.her!('U',alpha,x,A))
@test macroexpand(:(@her! A[:L] = alpha*x*x' + A)) == :(Base.LinAlg.BLAS.her!('L',alpha,x,A))
@test macroexpand(:(@her! A[:U] += alpha*x*x')) == :(Base.LinAlg.BLAS.her!('U',alpha,x,A))
@test macroexpand(:(@her! A[:L] += alpha*x*x')) == :(Base.LinAlg.BLAS.her!('L',alpha,x,A))

#herk!
@test macroexpand(:(@herk! C[:U] -= alpha*A*A')) == :(Base.LinAlg.BLAS.herk!('U','N',-alpha,A,1.0,C))
@test macroexpand(:(@herk! C[:L] -= alpha*A'*A)) == :(Base.LinAlg.BLAS.herk!('L','T',-alpha,A,1.0,C))
@test macroexpand(:(@herk! C[:U] = C - alpha*A*A')) == :(Base.LinAlg.BLAS.herk!('U','N',-alpha,A,1.0,C))
@test macroexpand(:(@herk! C[:L] = C - alpha*A'*A)) == :(Base.LinAlg.BLAS.herk!('L','T',-alpha,A,1.0,C))
@test macroexpand(:(@herk! C[:U] = beta*C - alpha*A*A')) == :(Base.LinAlg.BLAS.herk!('U','N',-alpha,A,beta,C))
@test macroexpand(:(@herk! C[:L] = beta*C - alpha*A'*A)) == :(Base.LinAlg.BLAS.herk!('L','T',-alpha,A,beta,C))
@test macroexpand(:(@herk! C[:U] += alpha*A*A')) == :(Base.LinAlg.BLAS.herk!('U','N',alpha,A,1.0,C))
@test macroexpand(:(@herk! C[:L] += alpha*A'*A)) == :(Base.LinAlg.BLAS.herk!('L','T',alpha,A,1.0,C))
@test macroexpand(:(@herk! C[:U] = alpha*A*A' + C)) == :(Base.LinAlg.BLAS.herk!('U','N',alpha,A,1.0,C))
@test macroexpand(:(@herk! C[:L] = C + alpha*A'*A)) == :(Base.LinAlg.BLAS.herk!('L','T',alpha,A,1.0,C))
@test macroexpand(:(@herk! C[:U] = alpha*A*A' + beta*C)) == :(Base.LinAlg.BLAS.herk!('U','N',alpha,A,beta,C))
@test macroexpand(:(@herk! C[:L] = alpha*A'*A + beta*C)) == :(Base.LinAlg.BLAS.herk!('L','T',alpha,A,beta,C))

#gbmv!
@test macroexpand(:(@gbmv! y = y - alpha*A[0:ku,h=2]*x)) == :(Base.LinAlg.BLAS.gbmv!('N',2,0,ku,-alpha,A,x,1.0,y))
@test macroexpand(:(@gbmv! y -= alpha*A[h=m,-kl:ku]*x)) == :(Base.LinAlg.BLAS.gbmv!('N',m,kl,ku,-alpha,A,x,1.0,y))
@test macroexpand(:(@gbmv! y = beta*y - alpha*A[0:ku,h=2]*x)) == :(Base.LinAlg.BLAS.gbmv!('N',2,0,ku,-alpha,A,x,beta,y))
@test macroexpand(:(@gbmv! y = beta*y - alpha*A[h=m,-kl:ku]*x)) == :(Base.LinAlg.BLAS.gbmv!('N',m,kl,ku,-alpha,A,x,beta,y))
@test macroexpand(:(@gbmv! y = beta*y - alpha*A[h=2, 0:ku]'*x)) == :(Base.LinAlg.BLAS.gbmv!('T',2,0,ku,-alpha,A,x,beta,y))
@test macroexpand(:(@gbmv! y = beta*y - alpha*A[kl:ku, h=m]'*x)) == :(Base.LinAlg.BLAS.gbmv!('T',m,-kl,ku,-alpha,A,x,beta,y))
@test macroexpand(:(@gbmv! y = alpha*A[0:ku,h=2]*x + y)) == :(Base.LinAlg.BLAS.gbmv!('N',2,0,ku,alpha,A,x,1.0,y))
@test macroexpand(:(@gbmv! y += alpha*A[h=m,-kl:ku]*x)) == :(Base.LinAlg.BLAS.gbmv!('N',m,kl,ku,alpha,A,x,1.0,y))
@test macroexpand(:(@gbmv! y = y + alpha*A[h=m,-kl:ku]*x)) == :(Base.LinAlg.BLAS.gbmv!('N',m,kl,ku,alpha,A,x,1.0,y))
@test macroexpand(:(@gbmv! y = alpha*A[0:ku,h=2]*x + beta*y)) == :(Base.LinAlg.BLAS.gbmv!('N',2,0,ku,alpha,A,x,beta,y))
@test macroexpand(:(@gbmv! y = alpha*A[h=m,-kl:ku]*x + beta*y)) == :(Base.LinAlg.BLAS.gbmv!('N',m,kl,ku,alpha,A,x,beta,y))
@test macroexpand(:(@gbmv! y = alpha*A[h=2, 0:ku]'*x + beta*y)) == :(Base.LinAlg.BLAS.gbmv!('T',2,0,ku,alpha,A,x,beta,y))
@test macroexpand(:(@gbmv! y = alpha*A[kl:ku, h=m]'*x + beta*y)) == :(Base.LinAlg.BLAS.gbmv!('T',m,-kl,ku,alpha,A,x,beta,y))

#sbmv!
@test macroexpand(:(@sbmv! y -= alpha*A[:U,0:k]*x)) == :(Base.LinAlg.BLAS.sbmv!('U',k,-alpha,A,x,1.0,y))
@test macroexpand(:(@sbmv! y -= alpha*A[0:k,:L]*x)) == :(Base.LinAlg.BLAS.sbmv!('L',k,-alpha,A,x,1.0,y))
@test macroexpand(:(@sbmv! y = y - alpha*A[:U,0:k]*x)) == :(Base.LinAlg.BLAS.sbmv!('U',k,-alpha,A,x,1.0,y))
@test macroexpand(:(@sbmv! y = beta*y - alpha*A[:U,0:k]*x)) == :(Base.LinAlg.BLAS.sbmv!('U',k,-alpha,A,x,beta,y))
@test macroexpand(:(@sbmv! y = beta*y - alpha*A[0:k,:U]*x)) == :(Base.LinAlg.BLAS.sbmv!('U',k,-alpha,A,x,beta,y))
@test macroexpand(:(@sbmv! y = beta*y - alpha*A[:L,0:k]*x)) == :(Base.LinAlg.BLAS.sbmv!('L',k,-alpha,A,x,beta,y))
@test macroexpand(:(@sbmv! y = beta*y - alpha*A[0:k,:L]*x)) == :(Base.LinAlg.BLAS.sbmv!('L',k,-alpha,A,x,beta,y))
@test macroexpand(:(@sbmv! y += alpha*A[:U,0:k]*x)) == :(Base.LinAlg.BLAS.sbmv!('U',k,alpha,A,x,1.0,y))
@test macroexpand(:(@sbmv! y += alpha*A[0:k,:L]*x)) == :(Base.LinAlg.BLAS.sbmv!('L',k,alpha,A,x,1.0,y))
@test macroexpand(:(@sbmv! y = alpha*A[:U,0:k]*x + y)) == :(Base.LinAlg.BLAS.sbmv!('U',k,alpha,A,x,1.0,y))
@test macroexpand(:(@sbmv! y = y + alpha*A[0:k,:L]*x)) == :(Base.LinAlg.BLAS.sbmv!('L',k,alpha,A,x,1.0,y))
@test macroexpand(:(@sbmv! y = alpha*A[:U,0:k]*x + beta*y)) == :(Base.LinAlg.BLAS.sbmv!('U',k,alpha,A,x,beta,y))
@test macroexpand(:(@sbmv! y = beta*y + alpha*A[0:k,:U]*x)) == :(Base.LinAlg.BLAS.sbmv!('U',k,alpha,A,x,beta,y))
@test macroexpand(:(@sbmv! y = alpha*A[:L,0:k]*x + beta*y)) == :(Base.LinAlg.BLAS.sbmv!('L',k,alpha,A,x,beta,y))
@test macroexpand(:(@sbmv! y = beta*y + alpha*A[0:k,:L]*x)) == :(Base.LinAlg.BLAS.sbmv!('L',k,alpha,A,x,beta,y))

#gemm!
@test macroexpand(:(@gemm! C -= alpha*A*B)) == :(Base.LinAlg.BLAS.gemm!('N','N',-alpha,A,B,1.0,C))
@test macroexpand(:(@gemm! C -= 1.5*A*B')) == :(Base.LinAlg.BLAS.gemm!('N','T',-1.5,A,B,1.0,C))
@test macroexpand(:(@gemm! C = C - alpha*A*B)) == :(Base.LinAlg.BLAS.gemm!('N','N',-alpha,A,B,1.0,C))
@test macroexpand(:(@gemm! C = C - 1.5*A*B')) == :(Base.LinAlg.BLAS.gemm!('N','T',-1.5,A,B,1.0,C))
@test macroexpand(:(@gemm! C = beta*C - alpha*A*B)) == :(Base.LinAlg.BLAS.gemm!('N','N',-alpha,A,B,beta,C))
@test macroexpand(:(@gemm! C = beta*C - 1.5*A*B')) == :(Base.LinAlg.BLAS.gemm!('N','T',-1.5,A,B,beta,C))
@test macroexpand(:(@gemm! C = beta*C - alpha*A'*B)) == :(Base.LinAlg.BLAS.gemm!('T','N',-alpha,A,B,beta,C))
@test macroexpand(:(@gemm! C = 3.4*C - alpha*A'*B')) == :(Base.LinAlg.BLAS.gemm!('T','T',-alpha,A,B,3.4,C))
@test macroexpand(:(@gemm! C += alpha*A*B)) == :(Base.LinAlg.BLAS.gemm!('N','N',alpha,A,B,1.0,C))
@test macroexpand(:(@gemm! C += 1.5*A*B')) == :(Base.LinAlg.BLAS.gemm!('N','T',1.5,A,B,1.0,C))
@test macroexpand(:(@gemm! C = alpha*A*B + C)) == :(Base.LinAlg.BLAS.gemm!('N','N',alpha,A,B,1.0,C))
@test macroexpand(:(@gemm! C = C + 1.5*A*B')) == :(Base.LinAlg.BLAS.gemm!('N','T',1.5,A,B,1.0,C))
@test macroexpand(:(@gemm! C = alpha*A*B + beta*C)) == :(Base.LinAlg.BLAS.gemm!('N','N',alpha,A,B,beta,C))
@test macroexpand(:(@gemm! C = beta*C + 1.5*A*B')) == :(Base.LinAlg.BLAS.gemm!('N','T',1.5,A,B,beta,C))
@test macroexpand(:(@gemm! C = alpha*A'*B + beta*C)) == :(Base.LinAlg.BLAS.gemm!('T','N',alpha,A,B,beta,C))
@test macroexpand(:(@gemm! C = 3.4*C + alpha*A'*B')) == :(Base.LinAlg.BLAS.gemm!('T','T',alpha,A,B,3.4,C))

#gemv!
@test macroexpand(:(@gemv! y -= alpha*A*x)) == :(Base.LinAlg.BLAS.gemv!('N',-alpha,A,x,1.0,y))
@test macroexpand(:(@gemv! y -= 1.5*A'*x)) == :(Base.LinAlg.BLAS.gemv!('T',-1.5,A,x,1.0,y))
@test macroexpand(:(@gemv! y = y - alpha*A*x)) == :(Base.LinAlg.BLAS.gemv!('N',-alpha,A,x,1.0,y))
@test macroexpand(:(@gemv! y = y - 1.5*A'*x)) == :(Base.LinAlg.BLAS.gemv!('T',-1.5,A,x,1.0,y))
@test macroexpand(:(@gemv! y = beta*y - alpha*A*x)) == :(Base.LinAlg.BLAS.gemv!('N',-alpha,A,x,beta,y))
@test macroexpand(:(@gemv! y = beta*y - 1.5*A'*x)) == :(Base.LinAlg.BLAS.gemv!('T',-1.5,A,x,beta,y))
@test macroexpand(:(@gemv! y += alpha*A*x)) == :(Base.LinAlg.BLAS.gemv!('N',alpha,A,x,1.0,y))
@test macroexpand(:(@gemv! y += 1.5*A'*x)) == :(Base.LinAlg.BLAS.gemv!('T',1.5,A,x,1.0,y))
@test macroexpand(:(@gemv! y = alpha*A*x + y)) == :(Base.LinAlg.BLAS.gemv!('N',alpha,A,x,1.0,y))
@test macroexpand(:(@gemv! y = y + 1.5*A'*x)) == :(Base.LinAlg.BLAS.gemv!('T',1.5,A,x,1.0,y))
@test macroexpand(:(@gemv! y = alpha*A*x + beta*y)) == :(Base.LinAlg.BLAS.gemv!('N',alpha,A,x,beta,y))
@test macroexpand(:(@gemv! y = beta*y + 1.5*A'*x)) == :(Base.LinAlg.BLAS.gemv!('T',1.5,A,x,beta,y))

#symm!
@test macroexpand(:(@symm! C[:L] -= alpha*A[:symm]*B)) == :(Base.LinAlg.BLAS.symm!('L','L',-alpha,A,B,1.0,C))
@test macroexpand(:(@symm! C[:U] -= 1.5*A*B[:symm])) == :(Base.LinAlg.BLAS.symm!('R','U',-1.5,A,B,1.0,C))
@test macroexpand(:(@symm! C[:L] = C - alpha*A[:symm]*B)) == :(Base.LinAlg.BLAS.symm!('L','L',-alpha,A,B,1.0,C))
@test macroexpand(:(@symm! C[:U] = C - 1.5*A*B[:symm])) == :(Base.LinAlg.BLAS.symm!('R','U',-1.5,A,B,1.0,C))
@test macroexpand(:(@symm! C[:L] = beta*C - alpha*A[:symm]*B)) == :(Base.LinAlg.BLAS.symm!('L','L',-alpha,A,B,beta,C))
@test macroexpand(:(@symm! C[:L] += alpha*A[:symm]*B)) == :(Base.LinAlg.BLAS.symm!('L','L',alpha,A,B,1.0,C))
@test macroexpand(:(@symm! C[:U] += 1.5*A*B[:symm])) == :(Base.LinAlg.BLAS.symm!('R','U',1.5,A,B,1.0,C))
@test macroexpand(:(@symm! C[:L] = C + alpha*A[:symm]*B)) == :(Base.LinAlg.BLAS.symm!('L','L',alpha,A,B,1.0,C))
@test macroexpand(:(@symm! C[:U] = 1.5*A*B[:symm] + C)) == :(Base.LinAlg.BLAS.symm!('R','U',1.5,A,B,1.0,C))
@test macroexpand(:(@symm! C[:L] = beta*C + alpha*A[:symm]*B)) == :(Base.LinAlg.BLAS.symm!('L','L',alpha,A,B,beta,C))

#symv!
@test macroexpand(:(@symv! y -= alpha*A[:U]*x)) == :(Base.LinAlg.BLAS.symv!('U',-alpha,A,x,1.0,y))
@test macroexpand(:(@symv! y -= 1.5*A[:L]*x)) == :(Base.LinAlg.BLAS.symv!('L',-1.5,A,x,1.0,y))
@test macroexpand(:(@symv! y = y - alpha*A[:U]*x)) == :(Base.LinAlg.BLAS.symv!('U',-alpha,A,x,1.0,y))
@test macroexpand(:(@symv! y = y - 1.5*A[:L]*x)) == :(Base.LinAlg.BLAS.symv!('L',-1.5,A,x,1.0,y))
@test macroexpand(:(@symv! y = beta*y - alpha*A[:U]*x)) == :(Base.LinAlg.BLAS.symv!('U',-alpha,A,x,beta,y))
@test macroexpand(:(@symv! y = beta*y - 1.5*A[:L]*x)) == :(Base.LinAlg.BLAS.symv!('L',-1.5,A,x,beta,y))
@test macroexpand(:(@symv! y += alpha*A[:U]*x)) == :(Base.LinAlg.BLAS.symv!('U',alpha,A,x,1.0,y))
@test macroexpand(:(@symv! y += 1.5*A[:L]*x)) == :(Base.LinAlg.BLAS.symv!('L',1.5,A,x,1.0,y))
@test macroexpand(:(@symv! y = alpha*A[:U]*x + y)) == :(Base.LinAlg.BLAS.symv!('U',alpha,A,x,1.0,y))
@test macroexpand(:(@symv! y = y + 1.5*A[:L]*x)) == :(Base.LinAlg.BLAS.symv!('L',1.5,A,x,1.0,y))
@test macroexpand(:(@symv! y = alpha*A[:U]*x + beta*y)) == :(Base.LinAlg.BLAS.symv!('U',alpha,A,x,beta,y))
@test macroexpand(:(@symv! y = beta*y + 1.5*A[:L]*x)) == :(Base.LinAlg.BLAS.symv!('L',1.5,A,x,beta,y))


text:
"""
    AbstractDimArray <: AbstractArray

Abstract supertype for all "dim" arrays.

These arrays return a `Tuple` of [`Dimension`](@ref)
from a [`dims`](@ref) method, and can be rebuilt using [`rebuild`](@ref).

`parent` must return the source array.

They should have [`metadata`](@ref), [`name`](@ref) and [`refdims`](@ref)
methods, although these are optional.

A [`rebuild`](@ref) method for `AbstractDimArray` must accept
`data`, `dims`, `refdims`, `name`, `metadata` arguments.

Indexing `AbstractDimArray` with non-range `AbstractArray` has undefined effects
on the `Dimension` index. Use forward-ordered arrays only"
"""
abstract type AbstractDimArray{T,N,D<:Tuple,A} <: AbstractArray{T,N} end

const AbstractDimVector = AbstractDimArray{T,1} where T
const AbstractDimMatrix = AbstractDimArray{T,2} where T

# DimensionalData.jl interface methods ####################################################

# Standard fields
dims(A::AbstractDimArray) = A.dims
refdims(A::AbstractDimArray) = A.refdims
data(A::AbstractDimArray) = A.data
name(A::AbstractDimArray) = A.name
metadata(A::AbstractDimArray) = A.metadata

layerdims(A::AbstractDimArray) = basedims(A)

"""
    rebuild(A::AbstractDimArray, data, [dims, refdims, name, metadata]) => AbstractDimArray
    rebuild(A::AbstractDimArray; kw...) => AbstractDimArray

Rebuild and `AbstractDimArray` with some field changes. All types
that inherit from `AbstractDimArray` must define this method if they
have any additional fields or alternate field order.

Implementations can discard arguments like `refdims`, `name` and `metadata`.

This method can also be used with keyword arguments in place of regular arguments.
"""
@inline function rebuild(
    A::AbstractDimArray, data, dims::Tuple=dims(A), refdims=refdims(A), name=name(A)
)
    rebuild(A, data, dims, refdims, name, metadata(A))
end

@inline rebuildsliced(args...) = rebuildsliced(getindex, args...)
@inline rebuildsliced(f::Function, A, data, I, name=name(A)) = rebuild(A, data, slicedims(f, A, I)..., name)

for func in (:val, :index, :lookup, :metadata, :order, :sampling, :span, :bounds, :locus)
    @eval ($func)(A::AbstractDimArray, args...) = ($func)(dims(A), args...)
end

Extents.extent(A::AbstractDimArray, args...) = Extents.extent(dims(A), args...)

# Array interface methods ######################################################

Base.size(A::AbstractDimArray) = size(parent(A))
Base.axes(A::AbstractDimArray) = axes(parent(A))
Base.iterate(A::AbstractDimArray, args...) = iterate(parent(A), args...)
Base.IndexStyle(A::AbstractDimArray) = Base.IndexStyle(parent(A))
Base.parent(A::AbstractDimArray) = data(A)
Base.vec(A::AbstractDimArray) = vec(parent(A))
@inline Base.axes(A::AbstractDimArray, dims::DimOrDimType) = axes(A, dimnum(A, dims))
@inline Base.size(A::AbstractDimArray, dims::DimOrDimType) = size(A, dimnum(A, dims))
# Only compare data and dim - metadata and refdims can be different
Base.:(==)(A1::AbstractDimArray, A2::AbstractDimArray) =
    parent(A1) == parent(A2) && dims(A1) == dims(A2)

const IDim = Dimension{<:StandardIndices}
function Base.checkbounds(::Type{Bool}, A::AbstractDimArray, dims::IDim...)
    Base.checkbounds(Bool, A, dims2indices(A, dims)...)
end
function Base.checkbounds(A::AbstractDimArray, dims::IDim...)
    Base.checkbounds(A, dims2indices(A, dims)...)
end

# undef constructor for Array, using dims
function Base.Array{T}(x::UndefInitializer, d1::Dimension, dims::Dimension...) where T
    Base.Array{T}(x, (d1, dims...))
end
Base.Array{T}(x::UndefInitializer, dims::DimTuple; kw...) where T = Array{T}(x, size(dims))

function Base.NamedTuple(A1::AbstractDimArray, As::AbstractDimArray...)
    arrays = (A1, As...)
    keys = map(Symbol ∘ name, arrays)
    NamedTuple{keys}(arrays)
end

# undef constructor for all AbstractDimArray
(::Type{A})(x::UndefInitializer, dims::Dimension...; kw...) where {A<:AbstractDimArray} = A(x, dims; kw...)
function (::Type{A})(x::UndefInitializer, dims::DimTuple; kw...) where {A<:AbstractDimArray{T}} where T
    basetypeof(A)(Array{T}(undef, size(dims)), dims; kw...)
end

# Dummy read methods that do nothing.
# Means can actually read subtypes that are not in-memory Arrays
Base.read(A::AbstractDimArray) = A

# Methods that create copies of an AbstractDimArray #######################################

# Need to cover a few type signatures to avoid ambiguity with base
Base.similar(A::AbstractDimArray) =
    rebuild(A, similar(parent(A)), dims(A), refdims(A), _noname(A))
Base.similar(A::AbstractDimArray, ::Type{T}) where T =
    rebuild(A, similar(parent(A), T), dims(A), refdims(A), _noname(A))
# We can't resize the dims or add missing dims, so return the unwraped Array type?
# An alternative would be to fill missing dims with `Anon`, and keep existing
# dims but strip the Lookup? It jsut seems a little complicated when the methods
# below using DimTuple work better anyway.
Base.similar(A::AbstractDimArray, i::Integer, I::Vararg{<:Integer}) =
    similar(A, eltype(A), (i, I...))
Base.similar(A::AbstractDimArray, I::Tuple{Int,Vararg{Int}}) =
    similar(A, eltype(A), I)
Base.similar(A::AbstractDimArray, ::Type{T}, i::Integer, I::Vararg{<:Integer}) where T =
    similar(A, T, (i, I...))
Base.similar(A::AbstractDimArray, ::Type{T}, I::Tuple{Int,Vararg{Int}}) where T =
    similar(parent(A), T, I)
# With Dimensions we can return an `AbstractDimArray`
Base.similar(A::AbstractDimArray, D::DimTuple) = Base.similar(A, eltype(A), D)
Base.similar(A::AbstractDimArray, D::Dimension...) = Base.similar(A, eltype(A), D)
Base.similar(A::AbstractDimArray, ::Type{T}, D::Dimension...) where T =
    Base.similar(A, T, D)
Base.similar(A::AbstractDimArray, ::Type{T}, D::DimTuple) where T =
    rebuild(A; data=similar(parent(A), T, size(D)), dims=D, refdims=())

# Keep the same type in `similar`
_noname(A::AbstractDimArray) = _noname(name(A))
_noname(::NoName) = NoName()
_noname(::Symbol) = Symbol("")
_noname(name::Name) = name # Keep the name so the type doesn't change

for func in (:copy, :one, :oneunit, :zero)
    @eval begin
        (Base.$func)(A::AbstractDimArray; kw...) = rebuild(A; data=($func)(parent(A)), kw...)
    end
end

Base.Array(A::AbstractDimArray) = Array(parent(A))
Base.collect(A::AbstractDimArray) = collect(parent(A))

_maybeunwrap(A::AbstractDimArray) = parent(A)
_maybeunwrap(A::AbstractArray) = A

for (d, s) in ((:AbstractDimArray, :AbstractDimArray),
               (:AbstractDimArray, :AbstractArray),
               (:AbstractArray, :AbstractDimArray))
    @eval begin
        Base.copy!(dst::$d{T,N}, src::$s{T,N}) where {T,N} = copy!(_maybeunwrap(dst), _maybeunwrap(src))
        Base.copy!(dst::$d{T,1}, src::$s{T,1}) where T = copy!(_maybeunwrap(dst), _maybeunwrap(src))
        Base.copyto!(dst::$d, src::$s) = copyto!(_maybeunwrap(dst), _maybeunwrap(src))
        Base.copyto!(dst::$d, dstart::Integer, src::$s) =
            copyto!(_maybeunwrap(dst), dstart, _maybeunwrap(src))
        Base.copyto!(dst::$d, dstart::Integer, src::$s, sstart::Integer) =
            copyto!(_maybeunwrap(dst), dstart, _maybeunwrap(src), sstart)
        Base.copyto!(dst::$d, dstart::Integer, src::$s, sstart::Integer, n::Integer) =
            copyto!(_maybeunwrap(dst), dstart, _maybeunwrap(src), sstart, n)
        Base.copyto!(dst::$d{T1,N}, Rdst::CartesianIndices{N}, src::$s{T2,N}, Rsrc::CartesianIndices{N}) where {T1,T2,N} =
            copyto!(_maybeunwrap(dst), Rdst, _maybeunwrap(src), Rsrc)
    end
end
Base.copy!(dst::SparseArrays.SparseVector, src::AbstractDimArray{T,1}) where T = copy!(dst, parent(src))

ArrayInterface.parent_type(::Type{<:AbstractDimArray{T,N,D,A}}) where {T,N,D,A} = A

function Adapt.adapt_structure(to, A::AbstractDimArray)
    rebuild(A,
        data=Adapt.adapt(to, parent(A)),
        dims=Adapt.adapt(to, dims(A)),
        refdims=Adapt.adapt(to, refdims(A)),
        name=Name(name(A)),
        metadata=Adapt.adapt(to, metadata(A)),
    )
end

# Concrete implementation ######################################################

"""
    DimArray <: AbstractDimArray

    DimArray(data, dims, refdims, name, metadata)
    DimArray(data, dims::Tuple; refdims=(), name=NoName(), metadata=NoMetadata())

The main concrete subtype of [`AbstractDimArray`](@ref).

`DimArray` maintains and updates its `Dimension`s through transformations and
moves dimensions to reference dimension `refdims` after reducing operations
(like e.g. `mean`).

## Arguments

- `data`: An `AbstractArray`.
- `dims`: A `Tuple` of `Dimension`
- `name`: A string name for the array. Shows in plots and tables.
- `refdims`: refence dimensions. Usually set programmatically to track past
    slices and reductions of dimension for labelling and reconstruction.
- `metadata`: `Dict` or `Metadata` object, or `NoMetadata()`

Indexing can be done with all regular indices, or with [`Dimension`](@ref)s
and/or [`Selector`](@ref)s.

Indexing `AbstractDimArray` with non-range `AbstractArray` has undefined effects
on the `Dimension` index. Use forward-ordered arrays only"

Example:

```julia
using Dates, DimensionalData

ti = (Ti(DateTime(2001):Month(1):DateTime(2001,12)),
x = X(10:10:100))
A = DimArray(rand(12,10), (ti, x), "example")

julia> A[X(Near([12, 35])), Ti(At(DateTime(2001,5)))];

julia> A[Near(DateTime(2001, 5, 4)), Between(20, 50)];
```
"""
struct DimArray{T,N,D<:Tuple,R<:Tuple,A<:AbstractArray{T,N},Na,Me} <: AbstractDimArray{T,N,D,A}
    data::A
    dims::D
    refdims::R
    name::Na
    metadata::Me
end
# 2 arg version
DimArray(data::AbstractArray, dims; kw...) = DimArray(data, (dims,); kw...)
function DimArray(data::AbstractArray, dims::Union{Tuple,NamedTuple};
    refdims=(), name=NoName(), metadata=NoMetadata()
)
    DimArray(data, format(dims, data), refdims, name, metadata)
end
# All keyword argument version
function DimArray(; data, dims, refdims=(), name=NoName(), metadata=NoMetadata())
    DimArray(data, dims; refdims, name, metadata)
end
# Construct from another AbstractDimArray
function DimArray(A::AbstractDimArray;
    data=data(A), dims=dims(A), refdims=refdims(A), name=name(A), metadata=metadata(A)
)
    DimArray(data, dims; refdims, name, metadata)
end
"""
    DimArray(f::Function, dim::Dimension; [name])

Apply function `f` across the values of the dimension `dim`
(using `broadcast`), and return the result as a dimensional array with
the given dimension. Optionally provide a name for the result.
"""
function DimArray(f::Function, dim::Dimension; name=Symbol(nameof(f), "(", name(dim), ")"))
     DimArray(f.(val(dim)), (dim,); name)
end

"""
    rebuild(A::DimArray, data, dims, refdims, name, metadata) => DimArray
    rebuild(A::DimArray; kw...) => DimArray

Rebuild a `DimArray` with new fields. Handling partial field
update is dealt with in `rebuild` for `AbstractDimArray`.
"""
@inline function rebuild(
    A::DimArray, data::AbstractArray, dims::Tuple, refdims::Tuple, name, metadata
)
    DimArray(data, dims, refdims, name, metadata)
end

"""
    Base.fill(x, dims::Dimension...; kw...) => DimArray
    Base.fill(x, dims::Tuple{Vararg{<:Dimension}}; kw...) => DimArray

Create a [`DimArray`](@ref) with a fill value of `x`.

There are two kinds of `Dimension` value acepted:
- A `Dimension` holding an `AbstractVector` will set the dimension index to
  that `AbstractVector`, and detect the dimension lookup.
- A `Dimension` holding an `Integer` will set the length of the axis,
  and set the dimension lookup to [`NoLookup`](@ref).

Keywords are the same as for [`DimArray`](@ref).

# Example
```@doctest
julia> using DimensionalData

julia> rand(Bool, X(2), Y(4))
2×4 DimArray{Bool,2} with dimensions: X, Y
 1  0  0  1
 1  0  1  1
```
"""
Base.fill

"""
    Base.rand(x, dims::Dimension...; kw...) => DimArray
    Base.rand(x, dims::Tuple{Vararg{<:Dimension}}; kw...) => DimArray
    Base.rand(r::AbstractRNG, x, dims::Tuple{Vararg{<:Dimension}}; kw...) => DimArray
    Base.rand(r::AbstractRNG, x, dims::Dimension...; kw...) => DimArray

Create a [`DimArray`](@ref) of random values.

There are two kinds of `Dimension` value acepted:
- A `Dimension` holding an `AbstractVector` will set the dimension index to
  that `AbstractVector`, and detect the dimension lookup.
- A `Dimension` holding an `Integer` will set the length of the axis,
  and set the dimension lookup to [`NoLookup`](@ref).

Keywords are the same as for [`DimArray`](@ref).

# Example
```julia
julia> using DimensionalData

julia> rand(Bool, X(2), Y(4))
2×4 DimArray{Bool,2} with dimensions: X, Y
 1  0  0  1
 1  0  1  1

julia> rand(X([:a, :b, :c]), Y(100.0:50:200.0))
3×3 DimArray{Float64,2} with dimensions:
  X: Symbol[a, b, c] Categorical: Unordered,
  Y: 100.0:50.0:200.0 Sampled: Ordered Regular Points
 0.43204   0.835111  0.624231
 0.752868  0.471638  0.193652
 0.484558  0.846559  0.455256
```
"""
Base.rand

"""
    Base.zeros(x, dims::Dimension...; kw...) => DimArray
    Base.zeros(x, dims::Tuple{Vararg{Dimension}}; kw...) => DimArray

Create a [`DimArray`](@ref) of zeros.

There are two kinds of `Dimension` value acepted:
- A `Dimension` holding an `AbstractVector` will set the dimension index to
  that `AbstractVector`, and detect the dimension lookup.
- A `Dimension` holding an `Integer` will set the length of the axis,
  and set the dimension lookup to [`NoLookup`](@ref).

Keywords are the same as for [`DimArray`](@ref).

# Example
```@doctest
julia> using DimensionalData

julia> zeros(Bool, X(2), Y(4))
2×4 DimArray{Bool,2} with dimensions: X, Y
 0  0  0  0
 0  0  0  0

julia> zeros(X([:a, :b, :c]), Y(100.0:50:200.0))
3×3 DimArray{Float64,2} with dimensions:
  X: Symbol[a, b, c] Categorical: Unordered,
  Y: 100.0:50.0:200.0 Sampled: Ordered Regular Points
 0.0  0.0  0.0
 0.0  0.0  0.0
 0.0  0.0  0.0
```
"""
Base.zeros

"""
    Base.ones(x, dims::Dimension...; kw...) => DimArray
    Base.ones(x, dims::Tuple{Vararg{Dimension}}; kw...) => DimArray

Create a [`DimArray`](@ref) of ones.

There are two kinds of `Dimension` value acepted:
- A `Dimension` holding an `AbstractVector` will set the dimension index to
  that `AbstractVector`, and detect the dimension lookup.
- A `Dimension` holding an `Integer` will set the length of the axis,
  and set the dimension lookup to [`NoLookup`](@ref).

Keywords are the same as for [`DimArray`](@ref).

# Example
```@doctest
julia> using DimensionalData

julia> ones(Bool, X(2), Y(4))
2×4 DimArray{Bool,2} with dimensions: X, Y
 1  1  1  1
 1  1  1  1

julia> ones(X([:a, :b, :c]), Y(100.0:50:200.0))
3×3 DimArray{Float64,2} with dimensions:
  X: Symbol[a, b, c] Categorical: Unordered,
  Y: 100.0:50.0:200.0 Sampled: Ordered Regular Points
 1.0  1.0  1.0
 1.0  1.0  1.0
 1.0  1.0  1.0
```
"""
Base.ones

# Dimension only DimArray creation methods

for f in (:zeros, :ones, :rand)
    @eval begin
        Base.$f(dim1::Dimension, dims::Dimension...; kw...) = $f((dim1, dims...); kw...)
        Base.$f(dims::DimTuple; kw...) = $f(Float64, dims; kw...)
    end
end
for f in (:trues, :falses)
    @eval begin
        Base.$f(dim1::Dimension, dims::Dimension...; kw...) = $f((dim1, dims...); kw...)
        function Base.$f(dims::DimTuple; kw...)
            C = dimconstructor(dims)
            C($f(_dimlength(dims)), _maybestripval(dims); kw...)
        end
    end
end
# Type specific DimArray creation methods
for f in (:zeros, :ones, :rand)
    @eval begin
        Base.$f(::Type{T}, d1::Dimension, dims::Dimension...; kw...) where T =
            $f(T, (d1, dims...); kw...)
        function Base.$f(::Type{T}, dims::DimTuple; kw...) where T
            C = dimconstructor(dims)
            C($f(T, _dimlength(dims)), _maybestripval(dims); kw...)
        end
    end
end
# Arbitrary object DimArray creation methods
for f in (:fill, :rand)
    @eval begin
        Base.$f(x, d1::Dimension, dims::Dimension...; kw...) = $f(x, (d1, dims...); kw...)
        function Base.$f(x, dims::DimTuple; kw...)
            A = $f(x, _dimlength(dims))
            C = dimconstructor(dims)
            C(A, _maybestripval(dims); kw...)
        end
    end
end
# AbstractRNG rand DimArray creation methods
Base.rand(r::AbstractRNG, x, d1::Dimension, dims::Dimension...; kw...) = rand(r, x, (d1, dims...); kw...)
function Base.rand(r::AbstractRNG, x, dims::DimTuple; kw...)
    C = dimconstructor(dims)
    C(rand(r, x, _dimlength(dims)), _maybestripval(dims); kw...)
end
function Base.rand(r::AbstractRNG, ::Type{T}, d1::Dimension, dims::Dimension...; kw...) where T
    rand(r, T, (d1, dims...); kw...)
end
function Base.rand(r::AbstractRNG, ::Type{T}, dims::DimTuple; kw...) where T
    C = dimconstructor(dims)
    C(rand(r, T, _dimlength(dims)), _maybestripval(dims); kw...)
end

_dimlength(dims::Tuple) = map(_dimlength, dims)
_dimlength(dim::Dimension{<:AbstractArray}) = length(dim)
_dimlength(dim::Dimension{<:Val{Keys}}) where Keys = length(Keys)
_dimlength(dim::Dimension{<:Integer}) = val(dim)
@noinline _dimlength(dim::Dimension) =
    throw(ArgumentError("$(basetypeof(dim)) must hold an Integer or an AbstractArray, instead holds: $(val(dim))"))

function _maybestripval(dims)
    dims = map(dims) do d
        val(d) isa AbstractArray ? d : basetypeof(d)()
    end
end

# dimconstructor
# Allow customising constructors based on dimension types
# Thed default constructor is DimArray
dimconstructor(dims::DimTuple) = dimconstructor(tail(dims))
dimconstructor(dims::Tuple{}) = DimArray