text:
using NiLang
using Test

@testset "vec dataview" begin
    @i function f(x::AbstractVector, y::AbstractMatrix)
        x .+= (y |> vec)
        vec(y)[5] += x[4]
    end
    x = zeros(25)
    y = ones(5,5)
    z = ones(5,5)
    z[5] = 2.0
    @instr f(x, y)
    @test y == z
end


text:
 # T refers to the result type
struct IndexFunArray{T, N, F} <: AbstractArray{T, N} where {F}
    # stores the generator function to be applied to the indices.
    generator::F
    # output size of the array
    size::NTuple{N, Int}

    # Constructor function
    function IndexFunArray(::Type{T}, gen::F, size::NTuple{N,Int}) where {T,N,F}
        res_type = gen(size) # here size serves only as a temp index to call gen with.
        if !(res_type isa T)
            throw(ArgumentError("The generator function does not have type $T as indicated, but type $(typeof(res_type))"))
        end
        return new{T, N, F}(gen, size)
    end
end

"""
    IndexFunArray([T], gen::F, size::NTuple{N,Int}) where {N,F}

Generate a IndexFunArray object which behaves like an array
but does not allocate the full array. Instead it calculates
the elements when needed. This is useful to prevent array allocations.
`gen` is a function which takes the array indices wrapped as tuple as input.
The output of `gen` determines the element type of the resulting array.
`size` is the output size of the resulting array.
`T` can be the optional element type of the arrays.
`gen` needs to have `T` as return type, otherwise the IndexFunArray
might be type unstable.

# Examples
```julia-repl
julia> IndexFunArray(x -> sum(x), (3, 3))
3×3 IndexFunArray{Int64, 2, var"#182#183"}:
 2  3  4
 3  4  5
 4  5  6

julia> IndexFunArray(x -> sum(abs2.(x)), (3, 3))
3×3 IndexFunArray{Int64, 2, var"#184#185"}:
  2   5  10
  5   8  13
 10  13  18

julia> IndexFunArray(x -> (x[1], x[2], "Julia"), (3,3))
3×3 IndexFunArray{Tuple{Int64, Int64, String}, 2, var"#18#19"}:
 (1, 1, "Julia")  (1, 2, "Julia")  (1, 3, "Julia")
 (2, 1, "Julia")  (2, 2, "Julia")  (2, 3, "Julia")
 (3, 1, "Julia")  (3, 2, "Julia")  (3, 3, "Julia")
```
"""
function IndexFunArray(gen::F, size::NTuple{N,Int}) where {N,F}
    # type T of the generator array is not provided
    # evaluate it once to get a type
    # but can be wrong if the generator function is not type stable
    T = typeof(gen(size))
    return IndexFunArray(T, gen, size)
end

# define AbstractArray function to allow to treat the generator as an array
# See https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array
Base.size(A::IndexFunArray) = A.size

# similar requires to be "mutable".
# So we might remove this
Base.similar(A::IndexFunArray, ::Type{T}=eltype(A), size::Dims=size(A)) where {T} =
    Array{T}(undef, size...) # IndexFunArray(A.generator, size)

# calculate the entry according to a vector of Int indices e.g. [1,2,3]
Base.getindex(A::IndexFunArray{T,N}, I::Vararg{Int, N}) where {T,N} =
    return A.generator(I)

# calculate the entry according to colons e.g. [:,:,:]
# Base.getindex(A::IndexFunArray{T,N}, c::Vararg{Colon, N}) where {T,N} =
# return A # just return the array itself

# calculate the entry according to colons e.g. [:]
# Base.getindex(A::IndexFunArray{T,N}, c::Colon) where {T,N} =
# return collect(Base.Iterators.flatten(A)) # just return the 1D version. You can collect, if needed.

# not supported
Base.setindex!(A::IndexFunArray{T,N}, v, I::Vararg{B,N}) where {T,N, B} = begin
    error("Attempt to assign entries to IndexFunArray which is immutable.")
end

ext: jl


text:
################################################################################
#
#   (9,3)a
#
################################################################################

# Implementation
# - implementation 1
# - labels <: Any
function getUnitcell_9_3_a(
			unitcell_type  :: Type{U},
			implementation :: Val{1}
		) :: U where {LS,LB,S<:AbstractSite{LS,3},B<:AbstractBond{LB,3},U<:AbstractUnitcell{S,B}}

	# define some constants
	a = [1.0, 0.0, 0.0]
	b = [-0.5, sqrt(3)/2., 0.0]
	c = [0.0, 0.0, sqrt(6*(4 + sqrt(3)))/(1 + 2*sqrt(3))]
	d_f = sqrt(3)/(1+2*sqrt(3))
	d_h = (29 - 3*sqrt(3))/132.
	# return a new Unitcell
	return newUnitcell(
		# Type of the unitcell
		U,
		# lattice vectors
		Vector{Float64}[
			-a./3 + b./3 + c./3,
			-a./3 + b.*-2/3 + c./3,
			a.*2/3. + b./3 + c./3,
		],
		# sites
		S[
			newSite(S, d_f * a, getDefaultLabelN(LS,1)),
			newSite(S, 2*d_h * a + d_h * b + c/12., getDefaultLabelN(LS,2)),
			newSite(S, d_f * (a + b), getDefaultLabelN(LS,3)),
			newSite(S, d_h * a + 2*d_h * b - c/12., getDefaultLabelN(LS,4)),
			newSite(S, d_f * b, getDefaultLabelN(LS,5)),
			newSite(S, -d_h *a + d_h * b + c/12., getDefaultLabelN(LS,6)),
			newSite(S, -d_f * a, getDefaultLabelN(LS,7)),
			newSite(S, -2*d_h * a - d_h * b - c/12., getDefaultLabelN(LS,8)),
			newSite(S, -d_f * (a + b), getDefaultLabelN(LS,9)),
			newSite(S, -d_h * a - 2*d_h*b + c/12., getDefaultLabelN(LS,10)),
			newSite(S, -d_f * b, getDefaultLabelN(LS,11)),
			newSite(S, d_h * a - d_h * b - c/12., getDefaultLabelN(LS,12)),
		],
		# bonds
		B[
			newBond(B, 1, 2, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 2, 3, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 3, 4, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 4, 5, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 5, 6, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 6, 7, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 7, 8, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 8, 9, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 9, 10, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 10, 11, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 11, 12, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 12, 1, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 2, 1, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 3, 2, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 4, 3, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 5, 4, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 6, 5, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 7, 6, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 8, 7, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 9, 8, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 10, 9, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 11, 10, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 12, 11, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 1, 12, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 3, 9, getDefaultLabel(LB), (0, -1, 1)),
			newBond(B, 9, 3, getDefaultLabel(LB), (0, 1, -1)),
			newBond(B, 1, 7, getDefaultLabel(LB), (-1, 0, 1)),
			newBond(B, 7, 1, getDefaultLabel(LB), (1, 0, -1)),
			newBond(B, 5, 11, getDefaultLabel(LB), (1, -1, 0)),
			newBond(B, 11, 5, getDefaultLabel(LB), (-1, 1, 0)),
			newBond(B, 12, 6, getDefaultLabel(LB), (-1, 0, 0)),
			newBond(B, 6, 12, getDefaultLabel(LB), (1, 0, 0)),
			newBond(B, 8, 2, getDefaultLabel(LB), (0, 0, -1)),
			newBond(B, 2, 8, getDefaultLabel(LB), (0, 0, 1)),
			newBond(B, 4, 10, getDefaultLabel(LB), (0, -1, 0)),
			newBond(B, 10, 4, getDefaultLabel(LB), (0, 1, 0)),
		]
	)
end

# Implementation
# - implementation 2 (alternative definition)
# - labels <: Any
function getUnitcell_9_3_a(
			unitcell_type  :: Type{U},
			implementation :: Val{2}
		) :: U where {LS,LB,S<:AbstractSite{LS,3},B<:AbstractBond{LB,3},U<:AbstractUnitcell{S,B}}

	# define some constants
	a1 = [-sqrt(3)/2., 1/2., 1/sqrt(3)]
	a2 = [0, -1, 1/sqrt(3)]
	a3 = [sqrt(3)/2, 1/2, 1/sqrt(3)]
	# return a new Unitcell
	return newUnitcell(
		# Type of the unitcell
		U,
		# lattice vectors
		Vector{Float64}[
			Float64[-sqrt(3)/2., 1/2., 1/sqrt(3)],
			Float64[0, -1, 1/sqrt(3)],
			Float64[sqrt(3)/2, 1/2, 1/sqrt(3)],
		],
		# sites
		S[
			newSite(S, Float64[0, 0, 0], getDefaultLabelN(LS,1)),
			newSite(S, a1./6. - a2./6., getDefaultLabelN(LS,2)),
			newSite(S, a1./3. - a2./3., getDefaultLabelN(LS,3)),
			newSite(S, a1./2. - a2./3. - a3./6., getDefaultLabelN(LS,4)),
			newSite(S, 2/3 .* a1 - a2./3. - a3./3., getDefaultLabelN(LS,5)),
			newSite(S, 2/3 .* a1 - a2./6. - a3./2., getDefaultLabelN(LS,6)),
			newSite(S, 2/3 .* a1 - 2/3 .* a3, getDefaultLabelN(LS,7)),
			newSite(S, a1./2. + a2./6. - 2/3 .*a3, getDefaultLabelN(LS,8)),
			newSite(S, a1./3. + a2./3. - 2/3 .*a3, getDefaultLabelN(LS,9)),
			newSite(S, a1./6. + a2./3. - a3./2., getDefaultLabelN(LS,10)),
			newSite(S, a2./3. - a3./3., getDefaultLabelN(LS,11)),
			newSite(S, a2./6. - a3./6., getDefaultLabelN(LS,12)),
		],
		# bonds
		B[
			newBond(B, 1, 2, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 2, 3, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 3, 4, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 4, 5, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 5, 6, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 6, 7, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 7, 8, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 8, 9, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 9, 10, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 10, 11, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 11, 12, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 12, 1, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 2, 1, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 3, 2, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 4, 3, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 5, 4, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 6, 5, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 7, 6, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 8, 7, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 9, 8, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 10, 9, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 11, 10, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 12, 11, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 1, 12, getDefaultLabel(LB), (0, 0, 0)),
			newBond(B, 1, 7, getDefaultLabel(LB), (-1, 0, 1)),
			newBond(B, 7, 1, getDefaultLabel(LB), (1, 0, -1)),
			newBond(B, 2, 8, getDefaultLabel(LB), (0, 0, 1)),
			newBond(B, 8, 2, getDefaultLabel(LB), (0, 0, -1)),
			newBond(B, 3, 9, getDefaultLabel(LB), (0, -1, 1)),
			newBond(B, 9, 3, getDefaultLabel(LB), (0, 1, -1)),
			newBond(B, 4, 10, getDefaultLabel(LB), (0, -1, 0)),
			newBond(B, 10, 4, getDefaultLabel(LB), (0, 1, 0)),
			newBond(B, 5, 11, getDefaultLabel(LB), (1, -1, 0)),
			newBond(B, 11, 5, getDefaultLabel(LB), (-1, 1, 0)),
			newBond(B, 6, 12, getDefaultLabel(LB), (1, 0, 0)),
			newBond(B, 12, 6, getDefaultLabel(LB), (-1, 0, 0)),
		]
	)
end

# Implementation
# - implementation 4 (Kitaev for 1)
# - labels <: Any
function getUnitcell_9_3_a(
			unitcell_type  :: Type{U},
			implementation :: Val{4}
		) :: U where {LS,LB,S<:AbstractSite{LS,3},B<:AbstractBond{LB,3},U<:AbstractUnitcell{S,B}}

	# define some constants
	a = [1.0, 0.0, 0.0]
	b = [-0.5, sqrt(3)/2., 0.0]
	c = [0.0, 0.0, sqrt(6*(4 + sqrt(3)))/(1 + 2*sqrt(3))]
	d_f = sqrt(3)/(1+2*sqrt(3))
	d_h = (29 - 3*sqrt(3))/132.
	# return a new Unitcell
	return newUnitcell(
		# Type of the unitcell
		U,
		# lattice vectors
        Vector{Float64}[
			-a./3 + b./3 + c./3,
			-a./3 + b.*-2/3 + c./3,
			a.*2/3. + b./3 + c./3,
		],
		# sites
		S[
			newSite(S, d_f * a, getDefaultLabelN(LS,1)),
			newSite(S, 2*d_h * a + d_h * b + c/12., getDefaultLabelN(LS,2)),
			newSite(S, d_f * (a + b), getDefaultLabelN(LS,3)),
			newSite(S, d_h * a + 2*d_h * b - c/12., getDefaultLabelN(LS,4)),
			newSite(S, d_f * b, getDefaultLabelN(LS,5)),
			newSite(S, -d_h *a + d_h * b + c/12., getDefaultLabelN(LS,6)),
			newSite(S, -d_f * a, getDefaultLabelN(LS,7)),
			newSite(S, -2*d_h * a - d_h * b - c/12., getDefaultLabelN(LS,8)),
			newSite(S, -d_f * (a + b), getDefaultLabelN(LS,9)),
			newSite(S, -d_h * a - 2*d_h*b + c/12., getDefaultLabelN(LS,10)),
			newSite(S, -d_f * b, getDefaultLabelN(LS,11)),
			newSite(S, d_h * a - d_h * b - c/12., getDefaultLabelN(LS,12)),
		],
		# bonds
		B[
			newBond(B, 1, 2, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 2, 3, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 3, 4, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 4, 5, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 5, 6, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 6, 7, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 7, 8, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 8, 9, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 9, 10, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 10, 11, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 11, 12, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 12, 1, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 2, 1, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 3, 2, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 4, 3, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 5, 4, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 6, 5, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 7, 6, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 8, 7, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 9, 8, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 10, 9, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 11, 10, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 12, 11, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 1, 12, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 3, 9, getDefaultLabelZ(LB), (0, -1, 1)),
			newBond(B, 9, 3, getDefaultLabelZ(LB), (0, 1, -1)),
			newBond(B, 1, 7, getDefaultLabelZ(LB), (-1, 0, 1)),
			newBond(B, 7, 1, getDefaultLabelZ(LB), (1, 0, -1)),
			newBond(B, 5, 11, getDefaultLabelZ(LB), (1, -1, 0)),
			newBond(B, 11, 5, getDefaultLabelZ(LB), (-1, 1, 0)),
			newBond(B, 12, 6, getDefaultLabelZ(LB), (-1, 0, 0)),
			newBond(B, 6, 12, getDefaultLabelZ(LB), (1, 0, 0)),
			newBond(B, 8, 2, getDefaultLabelZ(LB), (0, 0, -1)),
			newBond(B, 2, 8, getDefaultLabelZ(LB), (0, 0, 1)),
			newBond(B, 4, 10, getDefaultLabelZ(LB), (0, -1, 0)),
			newBond(B, 10, 4, getDefaultLabelZ(LB), (0, 1, 0)),
		]
	)
end

# Implementation
# - implementation 5 (Kitaev for 2)
# - labels <: Any
function getUnitcell_9_3_a(
			unitcell_type  :: Type{U},
			implementation :: Val{5}
		) :: U where {LS,LB,S<:AbstractSite{LS,3},B<:AbstractBond{LB,3},U<:AbstractUnitcell{S,B}}

	# define some constants
	a1 = [-sqrt(3)/2., 1/2., 1/sqrt(3)]
	a2 = [0, -1, 1/sqrt(3)]
	a3 = [sqrt(3)/2, 1/2, 1/sqrt(3)]
	# return a new Unitcell
	return newUnitcell(
		# Type of the unitcell
		U,
		# lattice vectors
		Vector{Float64}[
			Float64[-sqrt(3)/2., 1/2., 1/sqrt(3)],
			Float64[0, -1, 1/sqrt(3)],
			Float64[sqrt(3)/2, 1/2, 1/sqrt(3)],
		],
		# sites
		S[
			newSite(S, Float64[0, 0, 0], getDefaultLabelN(LS,1)),
			newSite(S, a1./6. - a2./6., getDefaultLabelN(LS,2)),
			newSite(S, a1./3. - a2./3., getDefaultLabelN(LS,3)),
			newSite(S, a1./2. - a2./3. - a3./6., getDefaultLabelN(LS,4)),
			newSite(S, 2/3 .* a1 - a2./3. - a3./3., getDefaultLabelN(LS,5)),
			newSite(S, 2/3 .* a1 - a2./6. - a3./2., getDefaultLabelN(LS,6)),
			newSite(S, 2/3 .* a1 - 2/3 .*a3, getDefaultLabelN(LS,7)),
			newSite(S, a1./2. + a2./6. - 2/3 .*a3, getDefaultLabelN(LS,8)),
			newSite(S, a1./3. + a2./3. - 2/3 .*a3, getDefaultLabelN(LS,9)),
			newSite(S, a1./6. + a2./3. - a3./2., getDefaultLabelN(LS,10)),
			newSite(S, a2./3. - a3./3., getDefaultLabelN(LS,11)),
			newSite(S, a2./6. - a3./6., getDefaultLabelN(LS,12)),
		],
		# bonds
		B[
			newBond(B, 1, 2, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 2, 3, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 3, 4, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 4, 5, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 5, 6, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 6, 7, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 7, 8, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 8, 9, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 9, 10, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 10, 11, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 11, 12, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 12, 1, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 2, 1, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 3, 2, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 4, 3, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 5, 4, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 6, 5, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 7, 6, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 8, 7, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 9, 8, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 10, 9, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 11, 10, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 12, 11, getDefaultLabelX(LB), (0, 0, 0)),
			newBond(B, 1, 12, getDefaultLabelY(LB), (0, 0, 0)),
			newBond(B, 1, 7, getDefaultLabelZ(LB), (-1, 0, 1)),
			newBond(B, 7, 1, getDefaultLabelZ(LB), (1, 0, -1)),
			newBond(B, 2, 8, getDefaultLabelZ(LB), (0, 0, 1)),
			newBond(B, 8, 2, getDefaultLabelZ(LB), (0, 0, -1)),
			newBond(B, 3, 9, getDefaultLabelZ(LB), (0, -1, 1)),
			newBond(B, 9, 3, getDefaultLabelZ(LB), (0, 1, -1)),
			newBond(B, 4, 10, getDefaultLabelZ(LB), (0, -1, 0)),
			newBond(B, 10, 4, getDefaultLabelZ(LB), (0, 1, 0)),
			newBond(B, 5, 11, getDefaultLabelZ(LB), (1, -1, 0)),
			newBond(B, 11, 5, getDefaultLabelZ(LB), (-1, 1, 0)),
			newBond(B, 6, 12, getDefaultLabelZ(LB), (1, 0, 0)),
			newBond(B, 12, 6, getDefaultLabelZ(LB), (-1, 0, 0)),
		]
	)
end


text:
module IceBlock

using ..Ahorn, Maple

const placements = Ahorn.PlacementDict(
    "Ice Block" => Ahorn.EntityPlacement(
        Maple.IceBlock,
        "rectangle"
    ),
)

Ahorn.minimumSize(entity::Maple.IceBlock) = 8, 8
Ahorn.resizable(entity::Maple.IceBlock) = true, true

Ahorn.selection(entity::Maple.IceBlock) = Ahorn.getEntityRectangle(entity)

edgeColor = (108, 214, 235, 255) ./ 255
centerColor = (76, 168, 214, 102) ./ 255

function Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::Maple.IceBlock, room::Maple.Room)
    x = Int(get(entity.data, "x", 0))
    y = Int(get(entity.data, "y", 0))

    width = Int(get(entity.data, "width", 32))
    height = Int(get(entity.data, "height", 32))

    Ahorn.drawRectangle(ctx, 0, 0, width, height, centerColor, edgeColor)
end

end


text:
### A Pluto.jl notebook ###
# v0.14.4

using Markdown
using InteractiveUtils

# ╔═╡ de259063-dff2-4270-86e4-d5d4a488b669
using Pkg, DrWatson

# ╔═╡ 1fc31cb5-0bf2-4909-b059-e1a7a2ba7b81
begin
	@quickactivate "NumericalMethodsforEngineers"
	using Symbolics, SymbolicUtils, ModelingToolkit
	using NumericalMethodsforEngineers, Test
end

# ╔═╡ f71fbec6-f64a-404b-923c-1dbf75563c2d
begin
	@parameters t
	@variables x y z(t)
end;

# ╔═╡ dcb8fd74-2514-41aa-ab11-d7b9b44518e2
begin
	ex = x + y + sin(z)
	L(ex)
end

# ╔═╡ a719fd68-fd4d-44b6-9bf4-f33f2afcc5a2
SymbolicUtils.istree(ex)

# ╔═╡ ce5dd824-9ff1-4fdc-99df-5c4b7bd5792a
L(substitute(ex, Dict([x => z, sin(z) => z^2])))

# ╔═╡ ed897d46-f288-48e5-99f7-d6a0efa1f24c
begin
	ex2 = x + y + sin(pi / 2)
	L(ex2)
end

# ╔═╡ e6c254bc-e6a5-40df-b560-93602cb3817e
begin
	substitute(ex2, Dict([x => 3, y => 1, z => 3]))
	L(ex2)
end

# ╔═╡ a3016072-aca5-45b5-9337-75fb8c09e33b
Symbolics.get_variables(ex)

# ╔═╡ aa6b5fc5-f290-4690-b604-ca96ba3b46ce
Symbolics.get_variables(ex2)

# ╔═╡ 9bbf267f-f712-4e69-8ff8-8cbcbea976d1
begin
	substitute(ex, Dict([x => 3, y => -2, z => pi/4]))
	L(ex)
end

# ╔═╡ Cell order:
# ╠═de259063-dff2-4270-86e4-d5d4a488b669
# ╠═1fc31cb5-0bf2-4909-b059-e1a7a2ba7b81
# ╠═f71fbec6-f64a-404b-923c-1dbf75563c2d
# ╠═dcb8fd74-2514-41aa-ab11-d7b9b44518e2
# ╠═a719fd68-fd4d-44b6-9bf4-f33f2afcc5a2
# ╠═ce5dd824-9ff1-4fdc-99df-5c4b7bd5792a
# ╠═ed897d46-f288-48e5-99f7-d6a0efa1f24c
# ╠═e6c254bc-e6a5-40df-b560-93602cb3817e
# ╠═a3016072-aca5-45b5-9337-75fb8c09e33b
# ╠═aa6b5fc5-f290-4690-b604-ca96ba3b46ce
# ╠═9bbf267f-f712-4e69-8ff8-8cbcbea976d1


text:
#=
Popis
  Funkcia vrati podgraf s vrcholmi ktore patria do k_corona.

Parametre
  g : datova struktura grafu :: GenericGraph
  k : stupen k_corona :: Int64
  core_numbers : slovnik obsahujuci indexy vrcholov a ich hodnotu jadra :: Dict{Int64,Int64}()

Navratova hodnota
  : k_corona podgraf vstupneho grafu :: GenericGraph

Poznamky
  Hodnota core_numbers je volitelna, ak nieje zadana tak prislusnost jednotlivych vrcholov
  do jadier je vypocitana funkciou coreness() zo vstupneho grafu.

  K_corona je podgraf, ktory obsahuje vrcholy z k_core, ktore maju presne k susedov.
=#

function k_corona(g::GenericGraph, k::Int64; core_numbers::Dict{Int64,Int64}=Dict{Int64,Int64}())

  if core_numbers == Dict{Int64,Int64}()
    core_numbers=coreness(g)
  end

  verts = Int64[]

  for (key,value) in core_numbers
    if value == k
      if count(x -> core_numbers[x.index] >= k, out_neighbors(get_vertex(key, g), g)) == k
        push!(verts, key)
      end
    end
  end

  return get_subgraph(verts, g)

end

max_stars_repo_name: mpuk/GraphAnalysis

max_issues_repo_name: mpuk/GraphAnalysis

max_forks_repo_name: mpuk/GraphAnalysis


text:
using HttpServer
using WebSockets
using MbedTLS

rel(p::String) = joinpath(dirname(@__FILE__), p)

wsh = WebSocketHandler() do req,client
        while true
            msg = read(client)
            write(client, msg)
        end
      end

cert = MbedTLS.crt_parse_file(rel("./certificate.crt"))
key = MbedTLS.parse_keyfile(rel("./privateKey.key"))

server = Server(wsh)
run(server, port=9999, ssl=(cert, key))


text:
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md

importall Base

using JuliaFEM
using JuliaFEM.Preprocess
using JuliaFEM.Postprocess

### Model definitions for ABAQUS data model

abstract AbstractMaterial
abstract AbstractMaterialProperty
abstract AbstractProperty
abstract AbstractStep
abstract AbstractBoundaryCondition
abstract AbstractOutputRequest

type Model
    path :: AbstractString
    name :: AbstractString
    mesh :: Mesh
    materials :: Dict{Symbol, AbstractMaterial}
    properties :: Vector{AbstractProperty}
    boundary_conditions :: Vector{AbstractBoundaryCondition}
    steps :: Vector{AbstractStep}
    problems :: Vector{Problem}
end

type SolidSection <: AbstractProperty
    element_set :: Symbol
    material_name :: Symbol
end

type Material <: AbstractMaterial
    name :: Symbol
    properties :: Vector{AbstractMaterialProperty}
end

type Elastic <: AbstractMaterialProperty
    E :: Float64
    nu :: Float64
end

type Step <: AbstractStep
    kind :: Nullable{Symbol} # STATIC, ...
    boundary_conditions :: Vector{AbstractBoundaryCondition}
    output_requests :: Vector{AbstractOutputRequest}
end

type BoundaryCondition <: AbstractBoundaryCondition
    kind :: Symbol # BOUNDARY, CLOAD, DLOAD, DSLOAD, ...
    data :: Vector
    options :: Dict
end

type OutputRequest <: AbstractOutputRequest
    kind :: Symbol # NODE, EL, SECTION, ...
    data :: Vector
    options :: Dict
    target :: Symbol # PRINT, FILE
end

### Utility functions to parse ABAQUS .inp file to data model

type Keyword
    name :: AbstractString
    options :: Vector{Union{AbstractString, Pair}}
end

function getindex(kw::Keyword, s)
    return parse(Dict(kw.options)[s])
end

type AbaqusReaderState
    section :: Nullable{Keyword}
    material :: Nullable{AbstractMaterial}
    property :: Nullable{AbstractProperty}
    step :: Nullable{AbstractStep}
    data :: Vector{AbstractString}
end

function get_data(state::AbaqusReaderState)
    data = []
    for row in state.data
        row = strip(row, [' ', ','])
        col = split(row, ',')
        col = map(parse, col)
        push!(data, col)
    end
    return data
end

function get_options(state::AbaqusReaderState)
    return Dict(get(state.section).options)
end

function get_option(state::AbaqusReaderState, what::AbstractString)
    return get_options(state)[what]
end

function length(state::AbaqusReaderState)
    return length(state.data)
end

function is_comment(line)
    return startswith(line, "**")
end

function is_keyword(line)
    return startswith(line, "*") && !is_comment(line)
end

function parse_keyword(line; uppercase_keyword=true)
    args = split(line, ",")
    args = map(strip, args)
    keyword_name = strip(args[1], '*')
    if uppercase_keyword
        keyword_name = uppercase(keyword_name)
    end
    keyword = Keyword(keyword_name, [])
    for option in args[2:end]
        pair = split(option, "=")
        if uppercase_keyword
            pair[1] = uppercase(pair[1])
        end
        if length(pair) == 1
            push!(keyword.options, pair[1])
        elseif length(pair) == 2
            push!(keyword.options, pair[1] => pair[2])
        else
            error("Keyword failure: $line, $option, $pair")
        end
    end
    return keyword
end

macro register_abaqus_keyword(keyword)
    underscored = Symbol(replace(keyword, " ", "_"))
    quote
        global is_abaqus_keyword_registered
        typealias $underscored Type{Val{Symbol($keyword)}}
        is_abaqus_keyword_registered(::Type{Val{Symbol($keyword)}}) = true
    end
end

function is_abaqus_keyword_registered(s::AbstractString)
    return is_abaqus_keyword_registered(Val{Symbol(s)})
end

function is_abaqus_keyword_registered(others)
    return false
end

function is_new_section(line)
    is_keyword(line) || return false
    section = parse_keyword(line)
    is_abaqus_keyword_registered(section.name) || return false
    return true
end

function maybe_close_section!(model, state; verbose=true)
    isnull(state.section) && return
    section_name = get(state.section).name
    verbose && info("Close section: $section_name")
    args = Tuple{Model, AbaqusReaderState, Type{Val{Symbol(section_name)}}}
    if method_exists(close_section!, args)
        close_section!(model, state, Val{Symbol(section_name)})
    else
        verbose && warn("no close_section! found for $section_name")
    end
    state.section = nothing
end

function maybe_open_section!(model, state; verbose=true)
    section_name = get(state.section).name
    section_options = get(state.section).options
    verbose && info("New section: $section_name with options $section_options")
    args = Tuple{Model, AbaqusReaderState, Type{Val{Symbol(section_name)}}}
    if method_exists(open_section!, args)
        open_section!(model, state, Val{Symbol(section_name)})
    else
        verbose && warn("no open_section! found for $section_name")
    end
end

function new_section!(model, state, line::AbstractString; verbose=true)
    maybe_close_section!(model, state; verbose=verbose)
    state.data = []
    state.section = parse_keyword(line)
    maybe_open_section!(model, state; verbose=verbose)
end

# open_section! is called right after keyword is found
function open_section! end

# close_section! is called at the end or section or before new keyword
function close_section! end

function process_line!(model, state, line; verbose=false)
    if isnull(state.section)
        verbose && info("section = nothing! line = $line")
        return
    end
    if is_keyword(line)
        warn("missing keyword? line = $line")
        # close section, this is probably keyword and collecting data should stop.
        maybe_close_section!(model, state)
        return
    end
    push!(state.data, line)
end

function abaqus_read_model(fn; read_mesh=true)

    model_path = dirname(fn)
    model_name = first(splitext(basename(fn)))
    model = Model(model_path, model_name, Mesh(), Dict(), [], [], [], [])

    if read_mesh
        model.mesh = abaqus_read_mesh(fn)
    end

    state = AbaqusReaderState(nothing, nothing, nothing, nothing, [])

    fid = open(fn)
    for line in eachline(fid)
        line = strip(line)
        is_comment(line) && continue
        if is_new_section(line)
            new_section!(model, state, line)
        else
            process_line!(model, state, line)
        end
    end
    close(fid)
    maybe_close_section!(model, state)

    return model
end

### Code to parse ABAQUS .inp to data model

# add here only keywords when planning to define open_section! and/or
# close_section!, i.e. actually parse keyword to model. little bit of
# magic is happening here, but after calling macro there is typealias
# defined i.e. typealias SOLID_SECTION Type{Val{Symbol("SOLID_SECTION")}}
# and also is_keyword_registered("SOLID SECTION") returns true after
# registration, also notice underscoring

@register_abaqus_keyword("SOLID SECTION")

@register_abaqus_keyword("MATERIAL")
@register_abaqus_keyword("ELASTIC")

@register_abaqus_keyword("STEP")
@register_abaqus_keyword("STATIC")
@register_abaqus_keyword("END STEP")

@register_abaqus_keyword("BOUNDARY")
@register_abaqus_keyword("CLOAD")
@register_abaqus_keyword("DLOAD")
@register_abaqus_keyword("DSLOAD")
typealias BOUNDARY_CONDITIONS Union{BOUNDARY, CLOAD, DLOAD, DSLOAD}

@register_abaqus_keyword("NODE PRINT")
@register_abaqus_keyword("EL PRINT")
@register_abaqus_keyword("SECTION PRINT")
typealias OUTPUT_REQUESTS Union{NODE_PRINT, EL_PRINT, SECTION_PRINT}

## Properties

function open_section!(model, state, ::SOLID_SECTION)
    element_set = get_option(state, "ELSET")
    material_name = get_option(state, "MATERIAL")
    property = SolidSection(element_set, material_name)
    state.property = property
    push!(model.properties, property)
end

function close_section!(model, state, ::SOLID_SECTION)
    state.property = nothing
end

## Materials

function open_section!(model, state, ::MATERIAL)
    material_name = Symbol(get_option(state, "NAME"))
    material = Material(material_name, [])
    state.material = material
    if haskey(model.materials, material_name)
        warn("Material $material_name already exists in model, skipping definition.")
    else
        model.materials[material_name] = material
    end
end

function close_section!(model, state, ::ELASTIC)
    # FIXME
    @assert length(state) == 1
    E, nu = first(get_data(state))
    material_property = Elastic(E, nu)
    material = get(state.material)
    push!(material.properties, material_property)
end

## Steps

function open_section!(model, state, ::STEP)
    step = Step(nothing, Vector(), Vector())
    state.step = step
    push!(model.steps, step)
end

function open_section!(model, state, ::STATIC)
    isnull(state.step) && error("*STATIC outside *STEP ?")
    get(state.step).kind = :STATIC
end

function open_section!(model, state, ::END_STEP)
    state.step = nothing
end

## Steps -- boundary conditions

function close_section!(model, state, ::BOUNDARY_CONDITIONS)
    kind = Symbol(get(state.section).name)
    data = get_data(state)
    options = get_options(state)
    bc = BoundaryCondition(kind, data, options)
    if isnull(state.step)
        push!(model.boundary_conditions, bc)
    else
        step = get(state.step)
        push!(step.boundary_conditions, bc)
    end
end

## Steps -- output requests

function close_section!(model, state, ::OUTPUT_REQUESTS)
    kind, target = map(parse, split(get(state.section).name, " "))
    data = get_data(state)
    options = get_options(state)
    request = OutputRequest(kind, data, options, target)
    step = get(state.step)
    push!(step.output_requests, request)
end

### Code to use JuliaFEM to run ABAQUS data model

function determine_problem_type(model::Model)
    # FIXME
    return Elasticity
end

function determine_problem_dimension(model::Model)
    # FIXME
    return 3
end

function get_element_section(model::Model, element_set_name::Symbol)
    sections = filter(s -> s.element_set == element_set_name, model.properties)
    length(sections) == 1 || error("Multiple sections found for element set $element_set_name")
    return sections[1]
end

function get_material(model::Model, material_name)
    return model.materials[material_name]
end

function create_problem(model::Model, element_set_name::Symbol; verbose=true)
    problem_type = determine_problem_type(model)
    problem_name = "$problem_type $element_set_name"
    problem_dimension = determine_problem_dimension(model)
    problem = Problem(problem_type, problem_name, problem_dimension)
    problem.elements = create_elements(model.mesh, element_set_name)
    section = get_element_section(model, element_set_name)
    material = get_material(model, section.material_name)
    for mp in material.properties
        if isa(mp, Elastic)
            verbose && info("$element_set_name: elastic material, E = $(mp.E), nu = $(mp.nu)")
            update!(problem.elements, "youngs modulus", mp.E)
            update!(problem.elements, "poissons ratio", mp.nu)
        end
    end
    return problem
end

""" Dirichlet boundary condition. """
function create_boundary_problem(model::Model, bc::AbstractBoundaryCondition, ::BOUNDARY; verbose=true)
    dim = determine_problem_dimension(model)
    problem = Problem(Dirichlet, "Dirichlet boundary *BOUNDARY", dim, "displacement")
    for row in bc.data

        if isa(row[1], AbstractString) # node set given
            nodes = model.mesh.node_sets[bc_name]
        else # single node given
            nodes = row[1]
        end

        elements = [Element(Poi1, [id]) for id in nodes]
        update!(elements, "geometry", model.mesh.nodes)

        for dof in row[2]:row[end]
            # FIXME
            val = 0.0
            update!(elements, "displacement $dof", val)
            verbose && info("Nodes ", join(nodes, ", "), " dof $dof => $val")
        end

        push!(problem, elements)
    end
    return problem
end

""" Distributed surface load (DSLOAD). """
function create_boundary_problem(model::Model, bc::AbstractBoundaryCondition, ::DSLOAD; verbose=false)
    dim = determine_problem_dimension(model)
    problem = Problem(Elasticity, "Distributed surface load *DSLOAD", dim)
    for row in bc.data
        bc_name, bc_type, pressure = row
        bc_type == :P || error("bc_type = $bc_type != :P")
        elements = []
        for (parent_element_id, parent_element_side) in model.mesh.surfaces[bc_name]
            parent_element_type = model.mesh.element_types[parent_element_id]
            parent_element_connectivity = model.mesh.elements[parent_element_id]

            child_element_type, child_element_lconn, child_element_connectivity =
                get_child_element(parent_element_type, parent_element_side,
                parent_element_connectivity)

            verbose && info("parent element : $parent_element_id, $parent_element_type, $parent_element_connectivity, $parent_element_side")
            verbose && info("child element  : $child_element_type, $child_element_connectivity")

            child_element = Element(JuliaFEM.(child_element_type), child_element_connectivity)
            push!(elements, child_element)
        end
        update!(elements, "geometry", model.mesh.nodes)
        update!(elements, "surface pressure", pressure)
        push!(problem, elements)
    end
    return problem
end

""" Distributed load (DLOAD). """
function create_boundary_problem(model::Model, bc::AbstractBoundaryCondition, ::DLOAD; verbose=false)
    dim = determine_problem_dimension(model)
    problem = Problem(Elasticity, "Distributed load *DLOAD", dim)
    for row in bc.data
        parent_element_id, parent_element_side, pressure = row
        parent_element_type = model.mesh.element_types[parent_element_id]
        parent_element_connectivity = model.mesh.elements[parent_element_id]

        child_element_type, child_element_lconn, child_element_connectivity =
            get_child_element(parent_element_type, parent_element_side,
            parent_element_connectivity)

        verbose && info("parent element : $parent_element_id, $parent_element_type, $parent_element_connectivity, $parent_element_side")
        verbose && info("child element  : $child_element_type, $child_element_connectivity")

        child_element = Element(JuliaFEM.(child_element_type), child_element_connectivity)
        update!(child_element, "geometry", model.mesh.nodes)
        update!(child_element, "surface pressure", -pressure)
        push!(problem.elements, child_element)
    end
    return problem
end

""" Concentrated load (CLOAD). """
function create_boundary_problem(model::Model, bc::AbstractBoundaryCondition, ::CLOAD; verbose=false)
    dim = determine_problem_dimension(model)
    problem = Problem(Elasticity, "Concentrated load *CLOAD", dim)
    nodes = sort(unique([row[1] for row in bc.data]))
    elements = Dict()
    for node in nodes
        element = Element(Poi1, [node])
        update!(element, "geometry", model.mesh.nodes)
        elements[node] = element
    end
    for row in bc.data
        node, dof, load = row
        update!(elements[node], "concentrated force $dof", load)
    end
    problem.elements = collect(values(elements))
    return problem
end

function create_boundary_problem(model::Model, bc::AbstractBoundaryCondition)
    create_boundary_problem(model, bc, Val{bc.kind})
end

""" Given element code, element side and global connectivity, determine boundary
element. E.g. for Tet4 we have 4 sides S1..S4 and boundary element is of type Tri3.
"""
function get_child_element(element_type::Symbol, element_side::Symbol,
                           element_connectivity::Vector{Int64})

    element_mapping = Dict(
        :Tet4 => Dict(
            :S1 => (:Tri3, [1, 2, 3]),
            :S2 => (:Tri3, [1, 4, 2]),
            :S3 => (:Tri3, [2, 4, 3]),
            :S4 => (:Tri3, [3, 4, 1])),
        :Hex8 => Dict(
            :P1 => (:Quad4, [1, 2, 3, 4]),
            :P2 => (:Quad4, [5, 8, 7, 6]),
            :P3 => (:Quad4, [1, 5, 6, 2]),
            :P4 => (:Quad4, [2, 6, 7, 3]),
            :P5 => (:Quad4, [3, 7, 8, 4]),
            :P6 => (:Quad4, [4, 8, 5, 1]))
        )

        if !haskey(element_mapping, element_type)
            error("Unable to find child element for element of type $element_type for side $element_side, check mapping.")
        end

        if !haskey(element_mapping[element_type], element_side)
            error("Unable to find child element side mapping for element of type $element_type for side $element_side, check mapping.")
        end

        child_element, child_element_lconn = element_mapping[element_type][element_side]
        child_element_gconn = element_connectivity[child_element_lconn]
        return child_element, child_element_lconn, child_element_gconn
    end

    function determine_solver_type(model::Model, step::AbstractStep)
        # FIXME
        return Linear
    end

    function process_output_request(model::Model, solver::Solver, output_request::AbstractOutputRequest)
        kind = Val{output_request.kind}
        target = Val{output_request.target}
    process_output_request(model, solver, output_request, kind, target)
end

function process_output_request(model::Model, solver::Solver, output_request::AbstractOutputRequest,
                                ::Type{Val{:NODE}}, ::Type{Val{:PRINT}})
    data = output_request.data
    options = output_request.options
    code_mapping = Dict(
        :COORD => "geometry",
        :U => "displacement",
        :CF => "concentrated force",
        :RF => "reaction force")
    abbr_mapping = Dict(:COORD => :COOR)
    for row in data
        info(repeat("-", 80))
        codes = join(row, ", ")
        info("*NODE PRINT request, with fields $codes")
        if length(options) != 0
            info("Additional options: $options")
        end
        info(repeat("-", 80))
        tables = Any[]
        for code in row
            haskey(code_mapping, code) || continue
            field_name = code_mapping[code]
            abbr = get(abbr_mapping, code, code)
            table = solver(DataFrame, field_name, abbr, solver.time)
            push!(tables, table)
        end
        length(tables) != 0 || continue
        results = join(tables..., on=:NODE, kind=:outer)
        sort!(results, cols=[:NODE])
        println()
        println(results)
        println()
    end
end

function process_output_request(model::Model, solver::Solver, output_request::AbstractOutputRequest,
                                ::Type{Val{:EL}}, ::Type{Val{:PRINT}})
    data = output_request.data
    options = output_request.options
    code_mapping = Dict(
        :COORD => "geometry",
        :S => "stress",
        :E => "strain")
    abbr_mapping = Dict(:COORD => :COOR)
    for row in data
        info(repeat("-", 80))
        codes = join(row, ", ")
        info("*EL PRINT request, with fields $codes")
        if length(options) != 0
            info("Additional options: $options")
        end
        info(repeat("-", 80))
        tables = Any[]
        for code in row
            haskey(code_mapping, code) || continue
            field_name = code_mapping[code]
            abbr = get(abbr_mapping, code, code)
            table = solver(DataFrame, solver.time, Val{code})
            push!(tables, table)
        end
        length(tables) != 0 || continue
        results = first(tables)
        if length(tables) > 1
            for i=2:length(tables)
                results = join(results, tables[i], on=:ELEMENT, kind=:outer)
            end
        end
        sort!(results, cols=[:ELEMENT, :IP])
        # filter out elements with id -1, they are automatically created boundary elements
        fel = find(results[:ELEMENT] .!= Symbol("E-1"))
        results = results[fel, :]
        println()
        println(results)
        println()
    end
end

function process_output_request(model::Model, solver::Solver, output_request::AbstractOutputRequest,
                                ::Type{Val{:SECTION}}, ::Type{Val{:PRINT}})
    data = output_request.data
    options = output_request.options
    info("SECTION PRINT output request, with data $data and options $options")
end

function call(model::Model)
    info("Starting JuliaFEM-ABAQUS solver.")

    # 1. create field problems and add elements
    element_sets = collect(keys(model.mesh.element_sets))
    info("Creating problems for element sets ", join(element_sets, ", "))
    model.problems = [create_problem(model, elset) for elset in element_sets]

    # 2. create boundary problems (the ones defined before *STEP)
    info("Boundary conditions defined before *STEP")
    for (i, bc) in enumerate(model.boundary_conditions)
        info("$i $(bc.kind)")
    end
    boundary_problems = [create_boundary_problem(model, bc) for bc in model.boundary_conditions]

    # 3. loop steps
    for step in model.steps
        # 3.1 add boundary conditions defined inside *STEP
        step_problems = [create_boundary_problem(model, bc) for bc in step.boundary_conditions]
        # 3.2 create solver and solve set of problems
        solver_type = determine_solver_type(model, step)
        solver_description = "$solver_type solver"
        solver = Solver(solver_type, solver_description)
        all_problems = [model.problems; boundary_problems; step_problems]
        push!(solver, all_problems...)
        solver()
        info(repeat("-", 80))
        info("Simulation ready, processing output requests")
        info(repeat("-", 80))
        # 3.3 postprocessing based on output requests
        for output_request in step.output_requests
            process_output_request(model, solver, output_request)
        end
    end

    return 0
end

function abaqus_download(name)
    fn = "$name.inp"
    if !haskey(ENV, "ABAQUS_DOWNLOAD_URL")
        info("""
        ABAQUS input file $fn not found and ABAQUS_DOWNLOAD_URL not set, unable to
        download file. To enable automatic model downloading, set environment variable
        ABAQUS_URL to point url to models.""")
        return 1
    end
    url = ENV["ABAQUS_DOWNLOAD_URL"]
    if haskey(ENV, "ABAQUS_DOWNLOAD_DIR")
        fn = rstrip(ENV["ABAQUS_DOWNLOAD_DIR"], '/') * "/" * fn
    end
    if !isfile(fn)
        info("Downloading model $name ...")
        download("$url/$name.inp", fn)
    end
    return 0
end

""" Return input file name. """
function abaqus_input_file_name(name)
    fn = "$name.inp"
    isfile(fn) && return fn
    if haskey(ENV, "ABAQUS_DOWNLOAD_DIR")
        fn = rstrip(ENV["ABAQUS_DOWNLOAD_DIR"], '/') * "/" * fn
    end
    isfile(fn) && return fn
    return ""
end

function abaqus_input_file_path(name)
    return dirname(abaqus_input_file_name(name))
end

function abaqus_open_results(name)
    path = abaqus_input_file_path(name)
    result_file = "$path/$name.xmf"
    return XDMF(result_file)
end

### JuliaFEM-ABAQUS interface entry point

"""
Run ABAQUS model. If input file is not found, attempt to fetch it from internet
if fetch is set to true and ABAQUS_DOWNLOAD_URL is set. Return exit code 0 if
execution of model is success.
"""
function abaqus_run_model(name; fetch=false, verbose=false)

    if !isfile("$name.inp") && fetch
        status = abaqus_download(name)
        status == 0 || return status # download failed
    end

    fn = abaqus_input_file_name(name)

    if verbose
        println(repeat("-", 80))
        println("Running ABAQUS model $name from file $fn")
        println(repeat("-", 80))
        println(readall(fn))
        println(repeat("-", 80))
    end

    model = abaqus_read_model(fn)
    status = model()
    return status
end


text:
# ---
# title: 234. Palindrome Linked List
# id: problem234
# author: Tian Jun
# date: 2020-10-31
# difficulty: Easy
# categories: Linked List, Two Pointers
# link: <https://leetcode.com/problems/palindrome-linked-list/description/>
# hidden: true
# ---
#
# Given a singly linked list, determine if it is a palindrome.
#
# **Example 1:**
#
#
#
#     Input: 1->2
#     Output: false
#
# **Example 2:**
#
#
#
#     Input: 1->2->2->1
#     Output: true
#
# **Follow up:**
# Could you do it in O(n) time and O(1) space?
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end


text:
export Batcher

abstract Batcher

max_stars_repo_name: unbornchikken/julia-ml-proto

max_issues_repo_name: unbornchikken/julia-ml-proto

max_forks_repo_name: unbornchikken/julia-ml-proto


text:
@testset "diff arithmetic" begin

    @testset "+" begin
        a = Diffed(1, NoChange())
        b = Diffed(2, NoChange())
        @test get_diff(a + b) == NoChange()
        @test strip_diff(a + b) == 3

        a = 1
        b = Diffed(2, NoChange())
        @test get_diff(a + b) == NoChange()
        @test strip_diff(a + b) == 3

        a = Diffed(1, NoChange())
        b = 2
        @test get_diff(a + b) == NoChange()
        @test strip_diff(a + b) == 3

        a = Diffed(1, UnknownChange())
        b = Diffed(2, UnknownChange())
        @test get_diff(a + b) == UnknownChange()
        @test strip_diff(a + b) == 3

        a = 1
        b = Diffed(2, UnknownChange())
        @test get_diff(a + b) == UnknownChange()
        @test strip_diff(a + b) == 3

        a = Diffed(1, UnknownChange())
        b = 2
        @test get_diff(a + b) == UnknownChange()
        @test strip_diff(a + b) == 3
    end

    # TODO test other binary operators
end

@testset "diff vectors" begin

    @testset "length" begin

    v = Diffed([1, 2, 3], NoChange())
    @test strip_diff(length(v)) == 3
    @test get_diff(length(v)) == NoChange()

    v = Diffed([1, 2, 3], UnknownChange())
    @test strip_diff(length(v)) == 3
    @test get_diff(length(v)) == UnknownChange()

    v = Diffed([1, 2, 3], VectorDiff(3, 4, Dict{Int,Diff}()))
    @test strip_diff(length(v)) == 3
    @test get_diff(length(v)) == IntDiff(-1)

    end

    @testset "getindex" begin

    v = [1, 2, 3]
    i = Diffed(2, UnknownChange())
    @test strip_diff(v[i]) == 2
    @test get_diff(v[i]) == UnknownChange()

    v = [1, 2, 3]
    i = Diffed(2, NoChange())
    @test strip_diff(v[i]) == 2
    @test get_diff(v[i]) == NoChange()

    v = [1, 2, 3]
    i = Diffed(2, IntDiff(1))
    @test strip_diff(v[i]) == 2
    @test get_diff(v[i]) == UnknownChange()

    v = Diffed([1, 2, 3], NoChange())
    @test strip_diff(v[2]) == 2
    @test get_diff(v[2]) == NoChange()

    v = Diffed([1, 2, 3], UnknownChange())
    @test strip_diff(v[2]) == 2
    @test get_diff(v[2]) == UnknownChange()

    # the value at v[2] was not changed
    v = Diffed([1, 2, 3], VectorDiff(3, 4, Dict{Int,Diff}()))
    @test strip_diff(v[2]) == 2
    @test get_diff(v[2]) == NoChange()

    # the value at v[2] was updated (reduced by 3)
    element_diff = IntDiff(-3)
    v = Diffed([1, 2, 3], VectorDiff(3, 4, Dict{Int,Diff}(2 => element_diff)))
    @test strip_diff(v[2]) == 2
    @test get_diff(v[2]) == element_diff
    end
end

@testset "diff dictionaries" begin
end

@testset "diff sets" begin
end


text:
function plot(bs::Bandstructure{1}; kw...)
    scene = bandplot2d(bs; kw...)
    axis = scene[Axis]
    axis[:names, :axisnames] = ("φ", "ε")
    return scene
end

function plot(bs::Bandstructure{2}; kw...)
    scene = bandplot3d(bs; kw...)
    axis = scene[Axis]
    to_value(scene[:show_axis]) && (axis[:names, :axisnames] = ("φ₁", "φ₂", "ε"))
    return scene
end

@recipe(BandPlot2D, bandstructure) do scene
    Theme(
    linewidth = 3,
    wireframe = true,
    colors = map(t -> RGBAf0((0.8 .* t)...),
        ((0.973, 0.565, 0.576), (0.682, 0.838, 0.922), (0.742, 0.91, 0.734),
         (0.879, 0.744, 0.894), (1.0, 0.84, 0.0), (1.0, 1.0, 0.669),
         (0.898, 0.762, 0.629), (0.992, 0.843, 0.93), (0.88, 0.88, 0.88)))
    )
end

function plot!(plot::BandPlot2D)
    bs = to_value(plot[1])
    bands = haskey(plot, :bands) ? to_value(plot[:bands]) : eachindex(bs.bands)
    colors = cycle(plot[:colors][])
    for (nb, color) in zip(bands, colors)
        band = bs.bands[nb]
        vertices = band.mesh.vertices
        simplices = band.simplices
        linesegments!(plot, (t -> vertices[first(t)] => vertices[last(t)]).(simplices),
                      linewidth = plot[:linewidth], color = color)
    end
    return plot
 end

@recipe(BandPlot3D, bandstructure) do scene
    Theme(
    linewidth = 1,
    wireframe = false,
    colors = map(t -> RGBAf0(t...),
        ((0.973, 0.565, 0.576), (0.682, 0.838, 0.922), (0.742, 0.91, 0.734),
         (0.879, 0.744, 0.894), (1.0, 0.84, 0.0), (1.0, 1.0, 0.669),
         (0.898, 0.762, 0.629), (0.992, 0.843, 0.93), (0.88, 0.88, 0.88)))
    )
end

function plot!(plot::BandPlot3D)
    bs = to_value(plot[1])
    bands = haskey(plot, :bands) ? to_value(plot[:bands]) : eachindex(bs.bands)
    colors = cycle(plot[:colors][])
    for (nb, color) in zip(bands, colors)
        band = bs.bands[nb]
        vertices = band.mesh.vertices
        connectivity = [s[j] for s in band.simplices, j in 1:3]
        if isempty(connectivity)
            scatter!(plot, vertices, color = color)
        else
            mesh!(plot, vertices, connectivity, color = color, transparency = false)
            if plot[:wireframe][]
                edgevertices = collect(Elsa.edgevertices(band.mesh))
                linesegments!(plot, edgevertices, linewidth = plot[:linewidth])
            end
        end
    end
    return plot
 end

function allpairs(simplex::NTuple{D,Int}, vertices) where D
    ntuple(i -> (i))
end


text:
# This file is a part of Julia. License is MIT: http://julialang.org/license

# Deprecated functions and objects
#
# Please add new deprecations at the bottom of the file.
# A function deprecated in a release will be removed in the next one.
# Please also add a reference to the pull request which introduced the
# deprecation.
#
# For simple cases where a direct replacement is available, use @deprecate:
# the first argument is the signature of the deprecated method, the second one
# is the call which replaces it. Remove the definition of the deprecated method
# and unexport it, as @deprecate takes care of calling the replacement
# and of exporting the function.
#
# For more complex cases, move the body of the deprecated method in this file,
# and call depwarn() directly from inside it. The symbol depwarn() expects is
# the name of the function, which is used to ensure that the deprecation warning
# is only printed the first time for each call place.

macro deprecate(old,new)
    meta = Expr(:meta, :noinline)
    if isa(old,Symbol)
        oldname = Expr(:quote,old)
        newname = Expr(:quote,new)
        Expr(:toplevel,
            Expr(:export,esc(old)),
            :(function $(esc(old))(args...)
                  $meta
                  depwarn(string($oldname," is deprecated, use ",$newname," instead."),
                          $oldname)
                  $(esc(new))(args...)
              end))
    elseif isa(old,Expr) && old.head == :call
        remove_linenums!(new)
        oldcall = sprint(io->show_unquoted(io,old))
        newcall = sprint(io->show_unquoted(io,new))
        oldsym = if isa(old.args[1],Symbol)
            old.args[1]
        elseif isa(old.args[1],Expr) && old.args[1].head == :curly
            old.args[1].args[1]
        else
            error("invalid usage of @deprecate")
        end
        oldname = Expr(:quote, oldsym)
        Expr(:toplevel,
            Expr(:export,esc(oldsym)),
            :($(esc(old)) = begin
                  $meta
                  depwarn(string($oldcall," is deprecated, use ",$newcall," instead."),
                          $oldname)
                  $(esc(new))
              end))
    else
        error("invalid usage of @deprecate")
    end
end

function depwarn(msg, funcsym)
    opts = JLOptions()
    if opts.depwarn > 0
        ln = Int(unsafe_load(cglobal(:jl_lineno, Cint)))
        fn = unsafe_string(unsafe_load(cglobal(:jl_filename, Ptr{Cchar})))
        bt = backtrace()
        caller = firstcaller(bt, funcsym)
        if opts.depwarn == 1 # raise a warning
            warn(msg, once=(caller != C_NULL), key=caller, bt=bt,
                 filename=fn, lineno=ln)
        elseif opts.depwarn == 2 # raise an error
            throw(ErrorException(msg))
        end
    end
    nothing
end

function firstcaller(bt::Array{Ptr{Void},1}, funcsym::Symbol)
    # Identify the calling line
    i = 1
    while i <= length(bt)
        lkups = StackTraces.lookup(bt[i])
        i += 1
        for lkup in lkups
            if lkup === StackTraces.UNKNOWN
                continue
            end
            if lkup.func == funcsym
                @goto found
            end
        end
    end
    @label found
    if i <= length(bt)
        return bt[i]
    end
    return C_NULL
end

deprecate(s::Symbol) = deprecate(current_module(), s)
deprecate(m::Module, s::Symbol) = ccall(:jl_deprecate_binding, Void, (Any, Any), m, s)

macro deprecate_binding(old, new)
    Expr(:toplevel,
         Expr(:export, esc(old)),
         Expr(:const, Expr(:(=), esc(old), esc(new))),
         Expr(:call, :deprecate, Expr(:quote, old)))
end

# 0.5 deprecations

for f in (:remotecall, :remotecall_fetch, :remotecall_wait)
    @eval begin
        @deprecate ($f)(w::LocalProcess, f::Function, args...)    ($f)(f, w::LocalProcess, args...)
        @deprecate ($f)(w::Worker, f::Function, args...)          ($f)(f, w::Worker, args...)
        @deprecate ($f)(id::Integer, f::Function, args...)        ($f)(f, id::Integer, args...)
    end
end

# 13232
@deprecate with_bigfloat_precision setprecision
@deprecate set_bigfloat_precision(prec) setprecision(prec)
@deprecate get_bigfloat_precision() precision(BigFloat)

@deprecate set_rounding setrounding
@deprecate with_rounding setrounding
@deprecate get_rounding rounding

#13465
@deprecate cov(x::AbstractVector; corrected=true, mean=Base.mean(x)) Base.covm(x, mean, corrected)
@deprecate cov(X::AbstractMatrix; vardim=1, corrected=true, mean=Base.mean(X, vardim)) Base.covm(X, mean, vardim, corrected)
@deprecate cov(x::AbstractVector, y::AbstractVector; corrected=true, mean=(Base.mean(x), Base.mean(y))) Base.covm(x, mean[1], y, mean[2], corrected)
@deprecate cov(X::AbstractVecOrMat, Y::AbstractVecOrMat; vardim=1, corrected=true, mean=(Base.mean(X, vardim), Base.mean(Y, vardim))) Base.covm(X, mean[1], Y, mean[2], vardim, corrected)

@deprecate cor(x::AbstractVector; mean=Base.mean(x)) Base.corm(x, mean)
@deprecate cor(X::AbstractMatrix; vardim=1, mean=Base.mean(X, vardim)) Base.corm(X, mean, vardim)
@deprecate cor(x::AbstractVector, y::AbstractVector; mean=(Base.mean(x), Base.mean(y))) Base.corm(x, mean[1], y, mean[2])
@deprecate cor(X::AbstractVecOrMat, Y::AbstractVecOrMat; vardim=1, mean=(Base.mean(X, vardim), Base.mean(Y, vardim))) Base.corm(X, mean[1], Y, mean[2], vardim)

@deprecate_binding SparseMatrix SparseArrays

#13496
@deprecate A_ldiv_B!(A::SparseMatrixCSC, B::StridedVecOrMat) A_ldiv_B!(factorize(A), B)

@deprecate chol(A::Number, ::Type{Val{:U}})         chol(A)
@deprecate chol(A::AbstractMatrix, ::Type{Val{:U}}) chol(A)
@deprecate chol(A::Number, ::Type{Val{:L}})         ctranspose(chol(A))
@deprecate chol(A::AbstractMatrix, ::Type{Val{:L}}) ctranspose(chol(A))

# Number updates

# rem1 is inconsistent for x==0: The result should both have the same
# sign as x, and should be non-zero.
function rem1{T<:Real}(x::T, y::T)
    depwarn("`rem1(x,y)` is discontinued, as it cannot be defined consistently for `x==0`. Rewrite the expression using `mod1` instead.", :rem1)
    rem(x-1,y)+1
end
rem1(x::Real, y::Real) = rem1(promote(x,y)...)
export rem1

# Filesystem module updates

@deprecate_binding FS Filesystem

isreadable(path...) = isreadable(stat(path...))
iswritable(path...) = iswritable(stat(path...))
isexecutable(path...) = isexecutable(stat(path...))
function isreadable(st::Filesystem.StatStruct)
    depwarn("isreadable is deprecated as it implied that the file would actually be readable by the user; consider using `isfile` instead. see also the system man page for `access`", :isreadable)
    return (st.mode & 0o444) > 0
end
function iswritable(st::Filesystem.StatStruct)
    depwarn("iswritable is deprecated as it implied that the file would actually be writable by the user; consider using `isfile` instead. see also the system man page for `access`", :iswritable)
    return (st.mode & 0o222) > 0
end
function isexecutable(st::Filesystem.StatStruct)
    depwarn("isexecutable is deprecated as it implied that the file would actually be executable by the user; consider using `isfile` instead. see also the system man page for `access`", :isexecutable)
    return (st.mode & 0o111) > 0
end
export isreadable, iswritable, isexecutable

@deprecate RemoteRef RemoteChannel

function tty_size()
    depwarn("tty_size is deprecated. use `displaysize(io)` as a replacement", :tty_size)
    if isdefined(Base, :active_repl)
        os = REPL.outstream(Base.active_repl)
        if isa(os, Terminals.TTYTerminal)
            return displaysize(os)
        end
    end
    if isdefined(Base, :STDOUT)
        return displaysize(STDOUT)
    end
    return displaysize()
end

# Combinatorics functions that have been moved out of base (#13897)
# Note: only the two-argument form of factorial has been moved
for deprecatedfunc in [:combinations, :factorial, :prevprod, :levicivita,
        :nthperm!, :nthperm, :parity, :partitions, :permutations]
    @eval begin
        $deprecatedfunc(args...) = error(string($deprecatedfunc, args,
            " has been moved to the package Combinatorics.jl.\n",
            "Run Pkg.add(\"Combinatorics\") to install Combinatorics on Julia v0.5 and later."))
        export $deprecatedfunc
    end
end

# Primes functions that have been moved out of base (#16481)
for deprecatedfunc in [:isprime, :primes, :primesmask, :factor]
    @eval begin
        $deprecatedfunc(args...) = error(string($deprecatedfunc, args,
            " has been moved to the package Primes.jl.\n",
            "Run Pkg.add(\"Primes\") to install Primes on Julia v0.5 and later, and then run `using Primes`."))
        export $deprecatedfunc
    end
end

#14335
@deprecate super(T::DataType) supertype(T)

function with_output_limit(thk, lim::Bool=true) # thk is usually show()
    depwarn("with_output_limit is deprecated. use `io = IOContext(io, :limit => lim)` as a replacement", :with_output_limit)
    global _limit_output
    last = _limit_output
    _limit_output = lim
    try
        thk()
    finally
        _limit_output = last
    end
end

#14555
@deprecate_binding Coff_t Int64
@deprecate_binding FileOffset Int64

#14474
macro boundscheck(yesno,blk)
    depwarn("The meaning of `@boundscheck` has changed. It now indicates that the provided code block performs bounds checking, and may be elided when inbounds.", Symbol("@boundscheck"))
    if yesno === true
        :(@inbounds $(esc(blk)))
    end
end

@deprecate parseip(str::AbstractString) parse(IPAddr, str)

#https://github.com/JuliaLang/julia/issues/14608
@deprecate readall readstring
@deprecate readbytes read

@deprecate field_offset(x::DataType, idx) fieldoffset(x, idx+1)
@noinline function fieldoffsets(x::DataType)
    depwarn("fieldoffsets is deprecated. use `map(idx->fieldoffset(x, idx), 1:nfields(x))` instead", :fieldoffsets)
    nf = nfields(x)
    offsets = Array{Int}(nf)
    for i = 1:nf
        offsets[i] = fieldoffset(x, i)
    end
    return offsets
end
export fieldoffsets

# 14766
@deprecate write(io::IO, p::Ptr, nb::Integer) unsafe_write(io, p, nb)

@deprecate isgeneric(f) isa(f,Function)

# need to do this manually since the front end deprecates method defs of `call`
const call = @eval function(f, args...; kw...)
    $(Expr(:meta, :noinline))
    depwarn("call(f,args...) is deprecated, use f(args...) instead.", :call)
    f(args...; kw...)
end
export call

# Changed issym to issymmetric. #15192
@deprecate issym issymmetric

# 15258
@deprecate scale(α::Number, A::AbstractArray) α*A
@deprecate scale(A::AbstractArray, α::Number) A*α
@deprecate scale(A::AbstractMatrix, x::AbstractVector) A*Diagonal(x)
@deprecate scale(x::AbstractVector, A::AbstractMatrix) Diagonal(x)*A

# 1933
@deprecate_binding SingleAsyncWork AsyncCondition

# #12872
@deprecate istext istextmime

#15409
# Deprecated definition of pmap with keyword arguments.
# deprecation warnings are in pmap.jl

# 15692
typealias Func{N} Function
deprecate(:Func)
for (Fun, func) in [(:IdFun, :identity),
                    (:AbsFun, :abs),
                    (:Abs2Fun, :abs2),
                    (:ExpFun, :exp),
                    (:LogFun, :log),
                    (:ConjFun, :conj),
                    (:AndFun, :&),
                    (:OrFun, :|),
                    (:XorFun, :xor),
                    (:AddFun, :+),
                    (:DotAddFun, :.+),
                    (:SubFun, :-),
                    (:DotSubFun, :.-),
                    (:MulFun, :*),
                    (:DotMulFun, :.*),
                    (:RDivFun, :/),
                    (:DotRDivFun, :./),
                    (:LDivFun, :\),
                    (:IDivFun, :div),
                    (:DotIDivFun, :.÷),
                    (:ModFun, :mod),
                    (:RemFun, :rem),
                    (:DotRemFun, :.%),
                    (:PowFun, :^),
                    (:MaxFun, :scalarmax),
                    (:MinFun, :scalarmin),
                    (:LessFun, :<),
                    (:MoreFun, :>),
                    (:DotLSFun, :.<<),
                    (:DotRSFun, :.>>),
                    (:ElementwiseMaxFun, :max),
                    (:ElementwiseMinFun, :min),
                    (:ComplexFun, :complex),
                    (:DotFun, :dot),
                    ]
    @eval begin
        @deprecate_binding $(Fun) typeof($(func))
        (::Type{typeof($(func))})() = $(func)
    end
end
@deprecate_binding CentralizedAbs2Fun typeof(centralizedabs2fun(0)).name.primary
(::Type{typeof(centralizedabs2fun(0)).name.primary})(m::Number) = centralizedabs2fun(m)
@deprecate specialized_unary(f::Function) f
@deprecate specialized_binary(f::Function) f
@deprecate specialized_bitwise_unary(f::Function) f
@deprecate specialized_bitwise_binary(f::Function) f

@deprecate bitunpack(B::BitArray) Array(B)
@deprecate bitpack(A::AbstractArray) BitArray(A)

# #4163
@deprecate xdump dump

@deprecate copy(x::AbstractString)  identity(x)
@deprecate copy(x::Tuple)  identity(x)

@deprecate sprandbool(m::Integer, n::Integer, density::AbstractFloat) sprand(Bool, m, n, density)
@deprecate sprandbool(r::AbstractRNG, m::Integer, n::Integer, density::AbstractFloat) sprand(r, Bool, m, n, density)
@deprecate sprandbool(n::Integer, density::AbstractFloat) sprand(Bool, n, density)
@deprecate sprandbool(r::AbstractRNG, n::Integer, density::AbstractFloat) sprand(r, Bool, n, density)
@deprecate sprand{T}(n::Integer, density::AbstractFloat, ::Type{T}) sprand(T, n, density)
@deprecate sprand{T}(r::AbstractRNG, n::Integer, density::AbstractFloat, ::Type{T}) sprand(r, T, n, density)

#15995
@deprecate symbol Symbol

#15032: Expressions like Base.(:+) now call broadcast.  Since calls
#       to broadcast(x, ::Symbol) are unheard of, and broadcast(x, ::Integer)
#       are unlikely, we can treat these as deprecated getfield calls.
#       (See julia-syntax.scm for the Base.(:+)(...) = ... deprecation.)
function broadcast(x::Any, i::Union{Integer,Symbol})
    depwarn("x.(i) is deprecated; use getfield(x, i) instead.", :broadcast)
    getfield(x, i)
end
# clearer to be more explicit in the warning for the Module case
function broadcast(m::Module, s::Symbol)
    S = repr(s) # 16295
    depwarn("$m.($S) is deprecated; use $m.$S or getfield($m, $S) instead.", :broadcast)
    getfield(m, s)
end
# expressions like f.(3) should still call broadcast for f::Function,
# and in general broadcast should work for scalar arguments, while
# getfield is certainly not intended for the case of f::Function.
broadcast(f::Function, i::Integer) = f(i)

#16167
macro ccallable(def)
    depwarn("@ccallable requires a return type", Symbol("@ccallable"))
    if isa(def,Expr) && (def.head === :(=) || def.head === :function)
        sig = def.args[1]
        if sig.head === :call
            name = sig.args[1]
            at = map(sig.args[2:end]) do a
                if isa(a,Expr) && a.head === :(::)
                    a.args[2]
                else
                    :Any
                end
            end
            return quote
                $(esc(def))
                let name = $(esc(name)), tt = $(Expr(:curly, :Tuple, map(esc, at)...))
                    rt = return_types(name, tt)
                    length(rt) == 1 || error("function not ccallable")
                    ccallable(name, rt[1], tt)
                end
            end
        end
    end
    error("expected method definition in @ccallable")
end

@deprecate_binding ASCIIString String
@deprecate_binding UTF8String String
@deprecate_binding ByteString String

@deprecate utf8(p::Ptr{UInt8}, len::Integer) unsafe_string(p, len)
@deprecate utf8(p::Ptr{UInt8}) unsafe_string(p)
@deprecate utf8(v::Vector{UInt8}) String(v)
@deprecate utf8(s::AbstractString) String(s)
@deprecate utf8(x) convert(String, x)

@deprecate ascii(p::Ptr{UInt8}, len::Integer) ascii(unsafe_string(p, len))
@deprecate ascii(p::Ptr{UInt8}) ascii(unsafe_string(p))
@deprecate ascii(v::Vector{UInt8}) ascii(String(v))
@deprecate ascii(x) ascii(convert(String, x))

@deprecate bytestring(s::Cstring) unsafe_string(s)
@deprecate bytestring(v::Vector{UInt8}) String(copy(v))
@deprecate bytestring(io::Base.AbstractIOBuffer) String(io)
@deprecate bytestring(p::Union{Ptr{Int8},Ptr{UInt8}}) unsafe_string(p)
@deprecate bytestring(p::Union{Ptr{Int8},Ptr{UInt8}}, len::Integer) unsafe_string(p,len)
@deprecate bytestring(s::AbstractString...) string(s...)
@deprecate String(s::Cstring) unsafe_string(s)
@deprecate String(p::Union{Ptr{Int8},Ptr{UInt8}}) unsafe_string(p)
@deprecate String(p::Union{Ptr{Int8},Ptr{UInt8}}, len::Integer) unsafe_string(p,len)

@deprecate(
    convert(::Type{String}, a::Vector{UInt8}, invalids_as::AbstractString),
    let a = a, invalids_as = invalids_as
        l = length(a)
        idx = 1
        iscopy = false
        while idx <= l
            if !is_valid_continuation(a[idx])
                nextidx = idx+1+utf8_trailing[a[idx]+1]
                (nextidx <= (l+1)) && (idx = nextidx; continue)
            end
            !iscopy && (a = copy(a); iscopy = true)
            endn = idx
            while endn <= l
                !is_valid_continuation(a[endn]) && break
                endn += 1
            end
            (endn > idx) && (endn -= 1)
            splice!(a, idx:endn, invalids_as.data)
            l = length(a)
        end
        String(a)
    end
)

@deprecate ==(x::Char, y::Integer) UInt32(x) == y
@deprecate ==(x::Integer, y::Char) x == UInt32(y)
# Note: when these deprecations are deleted, the specialized definitions isequal(x::Char, y::Integer)
# and isequal(x::Integer, y::Char) in operators.jl can be deleted, too
@deprecate isless(x::Char, y::Integer) UInt32(x) < y
@deprecate isless(x::Integer, y::Char) x < UInt32(y)

#6674 and #4233
macro windows(qm,ex)
    depwarn("`@windows` is deprecated, use `@static is_windows()` instead", Symbol("@windows"))
    return @static is_windows() ? esc(ex.args[1]) : esc(ex.args[2])
end
macro unix(qm,ex)
    depwarn("`@unix` is deprecated, use `@static is_unix()` instead", Symbol("@unix"))
    return @static is_unix() ? esc(ex.args[1]) : esc(ex.args[2])
end
macro osx(qm,ex)
    depwarn("`@osx` is deprecated, use `@static is_apple()` instead", Symbol("@osx"))
    return @static is_apple() ? esc(ex.args[1]) : esc(ex.args[2])
end
macro linux(qm,ex)
    depwarn("`@linux` is deprecated, use `@static is_linux()` instead", Symbol("@linux"))
    return @static is_linux() ? esc(ex.args[1]) : esc(ex.args[2])
end
macro windows_only(ex)
    depwarn("`@windows_only` is deprecated, use `@static if is_windows()` instead", Symbol("@windows_only"))
    return @static if is_windows() esc(ex) end
end
macro unix_only(ex)
    depwarn("`@unix_only` is deprecated, use `@static if is_unix()` instead", Symbol("@unix_only"))
    return @static if is_unix() esc(ex) end
end
macro osx_only(ex)
    depwarn("`@osx_only` is deprecated, use `@static if is_apple()` instead", Symbol("@osx_only"))
    return @static if is_apple() esc(ex) end
end
macro linux_only(ex)
    depwarn("`@linux_only` is deprecated, use `@static if is_linux()` instead", Symbol("@linux_only"))
    return @static if is_linux() esc(ex) end
end
export
    @windows,
    @unix,
    @osx,
    @linux,
    @windows_only,
    @unix_only,
    @osx_only,
    @linux_only

export OS_NAME
const OS_NAME =
    if Sys.KERNEL === :NT
        :Windows
    else
        Sys.KERNEL
    end
deprecate(:OS_NAME) # use Sys.KERNEL now

export CPU_CORES
function _set_CPU_CORES()
    global const CPU_CORES = Sys.CPU_CORES
    deprecate(Base, :CPU_CORES)
end
module Init_CPU_CORES
    const __init__ = Base._set_CPU_CORES
end

@deprecate_binding WORD_SIZE Sys.WORD_SIZE

@deprecate showcompact_lim show
@deprecate_binding writemime show

@deprecate blas_set_num_threads BLAS.set_num_threads

@deprecate print_escaped escape_string
@deprecate print_unescaped unescape_string
@deprecate print_joined join

@deprecate broadcast!_function(f) (B, As...) -> broadcast!(f, B, As...)
@deprecate broadcast_function(f)  (As...) -> broadcast(f, As...)

##### histogram #####

## nice-valued ranges for histograms
export hist, hist!, hist2d, hist2d!, histrange

function histrange{T<:AbstractFloat,N}(v::AbstractArray{T,N}, n::Integer)
    depwarn("histrange(...) is deprecated, use StatsBase.histrange(...) instead",:histrange)
    nv = length(v)
    if nv == 0 && n < 0
        throw(ArgumentError("number of bins must be ≥ 0 for an empty array, got $n"))
    elseif nv > 0 && n < 1
        throw(ArgumentError("number of bins must be ≥ 1 for a non-empty array, got $n"))
    end
    if nv == 0
        return 0.0:1.0:0.0
    end
    lo, hi = extrema(v)
    if hi == lo
        step = 1.0
    else
        bw = (hi - lo) / n
        e = 10.0^floor(log10(bw))
        r = bw / e
        if r <= 2
            step = 2*e
        elseif r <= 5
            step = 5*e
        else
            step = 10*e
        end
    end
    start = step*(ceil(lo/step)-1)
    nm1 = ceil(Int,(hi - start)/step)
    start:step:(start + nm1*step)
end

function histrange{T<:Integer,N}(v::AbstractArray{T,N}, n::Integer)
    depwarn("histrange(...) is deprecated, use StatsBase.histrange(...) instead",:histrange)
    nv = length(v)
    if nv == 0 && n < 0
        throw(ArgumentError("number of bins must be ≥ 0 for an empty array, got $n"))
    elseif nv > 0 && n < 1
        throw(ArgumentError("number of bins must be ≥ 1 for a non-empty array, got $n"))
    end
    if nv == 0
        return 0:1:0
    end
    if n <= 0
        throw(ArgumentError("number of bins n=$n must be positive"))
    end
    lo, hi = extrema(v)
    if hi == lo
        step = 1
    else
        bw = (Float64(hi) - Float64(lo)) / n
        e = 10.0^max(0,floor(log10(bw)))
        r = bw / e
        if r <= 1
            step = e
        elseif r <= 2
            step = 2*e
        elseif r <= 5
            step = 5*e
        else
            step = 10*e
        end
    end
    start = step*(ceil(lo/step)-1)
    nm1 = ceil(Int,(hi - start)/step)
    start:step:(start + nm1*step)
end

## midpoints of intervals
midpoints(r::Range) = r[1:length(r)-1] + 0.5*step(r)
midpoints(v::AbstractVector) = [0.5*(v[i] + v[i+1]) for i in 1:length(v)-1]

## hist ##
function sturges(n)  # Sturges' formula
    depwarn("sturges(n) is deprecated, use StatsBase.sturges(n) instead.",:sturges)
    n==0 && return one(n)
    ceil(Int,log2(n))+1
end

function hist!{HT}(h::AbstractArray{HT}, v::AbstractVector, edg::AbstractVector; init::Bool=true)
    depwarn("hist(...) and hist!(...) are deprecated. Use fit(Histogram,...) in StatsBase.jl instead.",:hist!)
    n = length(edg) - 1
    length(h) == n || throw(DimensionMismatch("length(histogram) must equal length(edges) - 1"))
    if init
        fill!(h, zero(HT))
    end
    for x in v
        i = searchsortedfirst(edg, x)-1
        if 1 <= i <= n
            h[i] += 1
        end
    end
    edg, h
end

hist(v::AbstractVector, edg::AbstractVector) = hist!(Array{Int,1}(length(edg)-1), v, edg)
hist(v::AbstractVector, n::Integer) = hist(v,histrange(v,n))
hist(v::AbstractVector) = hist(v,sturges(length(v)))

function hist!{HT}(H::AbstractArray{HT,2}, A::AbstractMatrix, edg::AbstractVector; init::Bool=true)
    depwarn("hist(...) and hist!(...) are deprecated. Use fit(Histogram,...) in StatsBase.jl instead.",:hist!)

    m, n = size(A)
    sH = size(H)
    sE = (length(edg)-1,n)
    sH == sE || throw(DimensionMismatch("incorrect size of histogram"))
    if init
        fill!(H, zero(HT))
    end
    for j = 1:n
        hist!(sub(H, :, j), sub(A, :, j), edg)
    end
    edg, H
end

hist(A::AbstractMatrix, edg::AbstractVector) = hist!(Array{Int,2}(length(edg)-1, size(A,2)), A, edg)
hist(A::AbstractMatrix, n::Integer) = hist(A,histrange(A,n))
hist(A::AbstractMatrix) = hist(A,sturges(size(A,1)))

## hist2d
function hist2d!{HT}(H::AbstractArray{HT,2}, v::AbstractMatrix,
                     edg1::AbstractVector, edg2::AbstractVector; init::Bool=true)
    depwarn("hist2d!(...) and hist2d(...) are deprecated. Use fit(Histogram,...) in StatsBase.jl instead.",:hist2d!)

    size(v,2) == 2 || throw(DimensionMismatch("hist2d requires an Nx2 matrix"))
    n = length(edg1) - 1
    m = length(edg2) - 1
    size(H) == (n, m) || throw(DimensionMismatch("incorrect size of histogram"))
    if init
        fill!(H, zero(HT))
    end
    for i = indices(v,1)
        x = searchsortedfirst(edg1, v[i,1]) - 1
        y = searchsortedfirst(edg2, v[i,2]) - 1
        if 1 <= x <= n && 1 <= y <= m
            @inbounds H[x,y] += 1
        end
    end
    edg1, edg2, H
end

hist2d(v::AbstractMatrix, edg1::AbstractVector, edg2::AbstractVector) =
    hist2d!(Array{Int,2}(length(edg1)-1, length(edg2)-1), v, edg1, edg2)

hist2d(v::AbstractMatrix, edg::AbstractVector) = hist2d(v, edg, edg)

hist2d(v::AbstractMatrix, n1::Integer, n2::Integer) =
    hist2d(v, histrange(sub(v,:,1),n1), histrange(sub(v,:,2),n2))
hist2d(v::AbstractMatrix, n::Integer) = hist2d(v, n, n)
hist2d(v::AbstractMatrix) = hist2d(v, sturges(size(v,1)))

@deprecate cell(dims::Integer...) Array{Any}(dims...)
@deprecate cell(dims::Tuple{Vararg{Integer}}) Array{Any}(dims)

@deprecate(pointer_to_array{T}(p::Ptr{T}, d::Union{Integer, Tuple{Vararg{Integer}}}, own::Bool=false),
    unsafe_wrap(Array, p, d, own))
@deprecate(pointer_to_string(p::Ptr{UInt8}, len::Integer, own::Bool=false),
    unsafe_wrap(String, p, len, own))
@deprecate(pointer_to_string(p::Ptr{UInt8}, own::Bool=false),
    unsafe_wrap(String, p, own))

function checkbounds(::Type{Bool}, sz::Integer, i)
    depwarn("checkbounds(Bool, size(A, d), i) is deprecated, use checkindex(Bool, indices(A, d), i).", :checkbounds)
    checkbounds(Bool, 1:sz, i)
end
immutable FakeArray{T,N} <: AbstractArray{T,N}
    dims::NTuple{N,Int}
end
size(A::FakeArray) = A.dims
function checkbounds{N,T}(::Type{Bool}, sz::NTuple{N,Integer}, I1::T, I...)
    depwarn("checkbounds(Bool, size(A), I...) is deprecated, use checkbounds(Bool, A, I...).", :checkbounds)
    checkbounds(Bool, FakeArray(sz), I1, I...)
end

function first(::Colon)
    depwarn("first(:) is deprecated, see http://docs.julialang.org/en/latest/devdocs/offset-arrays/", :first)
    1
end
function _first(i, A, d)
    depwarn("_first is deprecated, see http://docs.julialang.org/en/latest/devdocs/offset-arrays/", :_first)
    __first(i, A, d)
end
__first(::Colon, P, ::Colon) = first(linearindices(P))
__first(i, P, ::Colon) = first(i)
__first(::Colon, P, d) = first(indices(P, d))
__first(i, P, d) = first(i)

# Not exported, but deprecation may be useful just in case
function Broadcast.check_broadcast_shape(sz::Dims, As::Union{AbstractArray,Number}...)
    depwarn("check_broadcast_shape(size(A), B...) should be replaced with check_broadcast_shape(indices(A), B...)", :check_broadcast_shape)
    Broadcast.check_broadcast_shape(map(OneTo, sz), As...)
end

@deprecate trailingsize{n}(A::AbstractArray, ::Type{Val{n}}) trailingsize(A, n)

@deprecate slice view
@deprecate sub view

# Point users to SuiteSparse
function ereach{Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}, k::Integer, parent::Vector{Ti})
    error(string("ereach(A, k, parent) now lives in package SuiteSparse.jl. Run",
        "Pkg.add(\"SuiteSparse\") to install SuiteSparse on Julia v0.5."))
end
export etree
function etree{Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}, postorder::Bool)
    error(string("etree(A[, post]) now lives in package SuiteSparse.jl. Run",
        "Pkg.add(\"SuiteSparse\") to install SuiteSparse on Julia v0.5."))
end
etree(A::SparseMatrixCSC) = etree(A, false)
function csc_permute{Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}, pinv::Vector{Ti}, q::Vector{Ti})
    error(string("csc_permute(A, pinv, q) now lives in package SuiteSparse.jl. Run",
        "Pkg.add(\"SuiteSparse\") to install SuiteSparse on Julia v0.5."))
end
function symperm{Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}, pinv::Vector{Ti})
    error(string("symperm(A, pinv) now lives in package SuiteSparse.jl. Run,",
        "Pkg.add(\"SuiteSparse\") to install SuiteSparse on Julia v0.5."))
end

# Deprecate no-op transpose fallback. Please see #13171 and #17075.
function transpose(x)
    depwarn(string("the no-op `transpose` for non-numeric arrays is deprecated, ",
        "and no specific `transpose` method for $(typeof(x)) exists. Use ",
        "`permutedims(x, (2, 1))` for matrices and `reshape(x, 1, length(x))` for vectors, ",
        "or write a specific `transpose(x::$(typeof(x)))` method if appropriate."),
        :transpose)
    return x
end

@deprecate cholfact!(A::Base.LinAlg.HermOrSym, uplo::Symbol, ::Type{Val{false}}) cholfact!(A, Val{false})
@deprecate cholfact!(A::Base.LinAlg.HermOrSym, uplo::Symbol = :U) cholfact!(A)

# During the 0.5 development cycle, do not add any deprecations below this line
# To be deprecated in 0.6

const _oldstyle_array_vcat_ = false

@deprecate write(x) write(STDOUT::IO, x)

function delete!(::EnvHash, k::AbstractString, def)
    depwarn("`delete!(ENV, k, def)` should be replaced with `pop!(ENV, k, def)`. Be aware that `pop!` returns `k` or `def`, while `delete!` returns `ENV` or `def`.", :delete!)
    haskey(ENV,k) ? delete!(ENV,k) : def
end

@deprecate (+)(J::UniformScaling, x::Number) J.λ + x
@deprecate (+)(x::Number, J::UniformScaling) x + J.λ
@deprecate (-)(J::UniformScaling, x::Number) J.λ - x
@deprecate (-)(x::Number, J::UniformScaling) x - J.λ

# Deprecate methods that convert Diagonal and Bidiagonal to <:AbstractTriangular.
function convert(::Type{UpperTriangular}, A::Diagonal)
    depwarn(string("`convert(::Type{UpperTriangular}, A::Diagonal)` and other methods ",
        "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ",
        "Consider calling the `UpperTriangular` constructor directly ",
        "(`UpperTriangular(A)`) instead."), :convert)
    UpperTriangular(A)
end
function convert(::Type{LowerTriangular}, A::Diagonal)
    depwarn(string("`convert(::Type{LowerTriangular}, A::Diagonal)` and other methods ",
        "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ",
        "Consider calling the `LowerTriangular` constructor directly ",
        "(`LowerTriangular(A)`) instead."), :convert)
    LowerTriangular(A)
end
function convert(::Type{Base.LinAlg.UnitUpperTriangular}, A::Diagonal)
    depwarn(string("`convert(::Type{UnitUpperTriangular}, A::Diagonal)` and other methods ",
        "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ",
        "Consider calling the `UnitUpperTriangular` constructor directly ",
        "(`Base.LinAlg.UnitUpperTriangular(A)`) instead."), :convert)
    if !all(A.diag .== one(eltype(A)))
        throw(ArgumentError("matrix cannot be represented as UnitUpperTriangular"))
    end
    Base.LinAlg.UnitUpperTriangular(Array(A))
end
function convert(::Type{Base.LinAlg.UnitLowerTriangular}, A::Diagonal)
    depwarn(string("`convert(::Type{UnitLowerTriangular}, A::Diagonal)` and other methods ",
        "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ",
        "Consider calling the `UnitLowerTriangular` constructor directly ",
        "(`Base.LinAlg.UnitLowerTriangular(A)`) instead."), :convert)
    if !all(A.diag .== one(eltype(A)))
        throw(ArgumentError("matrix cannot be represented as UnitLowerTriangular"))
    end
    Base.LinAlg.UnitLowerTriangular(Array(A))
end
function convert(::Type{LowerTriangular}, A::Bidiagonal)
    depwarn(string("`convert(::Type{LowerTriangular}, A::Bidiagonal)` and other methods ",
        "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ",
        "Consider calling the `LowerTriangular` constructor directly (`LowerTriangular(A)`) ",
        "instead."), :convert)
    if !A.isupper
        LowerTriangular(Array(A))
    else
        throw(ArgumentError("Bidiagonal matrix must have lower off diagonal to be converted to LowerTriangular"))
    end
end
function convert(::Type{UpperTriangular}, A::Bidiagonal)
    depwarn(string("`convert(::Type{UpperTriangular}, A::Bidiagonal)` and other methods ",
        "that convert `Diagoinal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ",
        "Consider calling the `UpperTriangular` constructor directly (`UpperTriangular(A)`) ",
        "instead."), :convert)
    if A.isupper
        UpperTriangular(Array(A))
    else
        throw(ArgumentError("Bidiagonal matrix must have upper off diagonal to be converted to UpperTriangular"))
    end
end

# Deprecate vectorized unary functions over sparse matrices in favor of compact broadcast syntax (#17265).
for f in (:sin, :sinh, :sind, :asin, :asinh, :asind,
        :tan, :tanh, :tand, :atan, :atanh, :atand,
        :sinpi, :cosc, :ceil, :floor, :trunc, :round, :real, :imag,
        :log1p, :expm1, :abs, :abs2,
        :log, :log2, :log10, :exp, :exp2, :exp10, :sinc, :cospi,
        :cos, :cosh, :cosd, :acos, :acosd,
        :cot, :coth, :cotd, :acot, :acotd,
        :sec, :sech, :secd, :asech,
        :csc, :csch, :cscd, :acsch)
    @eval @deprecate $f(A::SparseMatrixCSC) $f.(A)
end

# For deprecating vectorized functions in favor of compact broadcast syntax
macro dep_vectorize_1arg(S, f)
    S = esc(S)
    f = esc(f)
    T = esc(:T)
    x = esc(:x)
    AbsArr = esc(:AbstractArray)
    :( @deprecate $f{$T<:$S}($x::$AbsArr{$T}) $f.($x) )
end
macro dep_vectorize_2arg(S, f)
    S = esc(S)
    f = esc(f)
    T1 = esc(:T1)
    T2 = esc(:T2)
    x = esc(:x)
    y = esc(:y)
    AbsArr = esc(:AbstractArray)
    quote
        @deprecate $f{$T1<:$S}($x::$S, $y::$AbsArr{$T1}) $f.($x,$y)
        @deprecate $f{$T1<:$S}($x::$AbsArr{$T1}, $y::$S) $f.($x,$y)
        @deprecate $f{$T1<:$S,$T2<:$S}($x::$AbsArr{$T1}, $y::$AbsArr{$T2}) $f.($x,$y)
    end
end

# Deprecate @vectorize_1arg-vectorized functions from...
for f in (
        # base/special/trig.jl
        :sinpi, :cospi, :sinc, :cosc,
        # base/special/log.jl
        :log, :log1p,
        # base/special/gamma.jl
        :gamma, :lfact, :digamma, :trigamma, :zeta, :eta,
        # base/special/erf.jl
        :erfcx, :erfi, :dawson,
        # base/special/bessel.jl
        :airyprime, :airyai, :airyaiprime, :airybi, :airybiprime,
        :airy, :airyx, :besselj0, :besselj1, :bessely0, :bessely1,
        # base/math.jl
        :cbrt, :sinh, :cosh, :tanh, :atan, :asinh, :exp, :erf, :erfc, :exp2,
        :expm1, :exp10, :sin, :cos, :tan, :asin, :acos, :acosh, :atanh,
        #=:log,=# :log2, :log10, :lgamma, #=:log1p,=# :sqrt,
        # base/floatfuncs.jl
        :abs, :abs2, :angle, :isnan, :isinf, :isfinite,
        # base/complex.jl
        :cis,
        )
    @eval @dep_vectorize_1arg Number $f
end
# base/fastmath.jl
for f in ( :acos_fast, :acosh_fast, :angle_fast, :asin_fast, :asinh_fast,
            :atan_fast, :atanh_fast, :cbrt_fast, :cis_fast, :cos_fast,
            :cosh_fast, :exp10_fast, :exp2_fast, :exp_fast, :expm1_fast,
            :lgamma_fast, :log10_fast, :log1p_fast, :log2_fast, :log_fast,
            :sin_fast, :sinh_fast, :sqrt_fast, :tan_fast, :tanh_fast )
    eval(FastMath, :(Base.@dep_vectorize_1arg Number $f))
end
for f in (
        :invdigamma, # base/special/gamma.jl
        :erfinc, :erfcinv, # base/special/erf.jl
        :trunc, :floor, :ceil, :round, # base/floatfuncs.jl
        :rad2deg, :deg2rad, :exponent, :significand, # base/math.jl
        :sind, :cosd, :tand, :asind, :acosd, :atand, :asecd, :acscd, :acotd, # base/special/trig.jl
        )
    @eval @dep_vectorize_1arg Real $f
end
# base/complex.jl
@dep_vectorize_1arg Complex round
@dep_vectorize_1arg Complex float
# base/dates/*.jl
for f in (:unix2datetime, :rata2datetime, :julian2datetime)  # base/dates/conversions.jl
    eval(Dates, :(Base.@dep_vectorize_1arg Real $f))
end
for f in (
        # base/dates/accessors.jl
        :year, :month, :day, :week, :dayofmonth, :yearmonth, :monthday, :yearmonthday,
        # base/dates/adjusters.jl
        :firstdayofweek, :lastdayofweek, :firstdayofmonth,
        :lastdayofmonth, :firstdayofyear, :lastdayofyear,
        :firstdayofquarter, :lastdayofquarter,
        # base/dates/query.jl
        :dayname, :dayabbr, :dayofweek, :dayofweekofmonth,
        :daysofweekinmonth, :monthname, :monthabbr, :daysinmonth,
        :isleapyear, :dayofyear, :daysinyear, :quarterofyear, :dayofquarter,
    )
    eval(Dates, :(Base.@dep_vectorize_1arg Dates.TimeType $f))
end
for f in (
    :hour, :minute, :second, :millisecond, # base/dates/accessors.jl
    :Date, :datetime2unix, :datetime2rata, :datetime2julian, # base/dates/conversions.jl
    )
    eval(Dates, :(Base.@dep_vectorize_1arg Dates.DateTime $f))
end
eval(Dates, :(Base.@dep_vectorize_1arg Dates.Date Datetime)) # base/dates/conversions.jl

# Deprecate @vectorize_2arg-vectorized functions from...
for f in (
        # base/special/gamma.jl
        :polygamma, :zeta, :beta, :lbeta,
        # base/special/bessel.jl
        :airy, :airyx, :besseli, :besselix, :besselj, :besseljx,
        :besselk, :besselkx, :bessely, :besselyx, :besselh,
        :besselhx, :hankelh1, :hankelh2, :hankelh1x, :hankelh2x,
        # base/math.jl
        :log, :hypot, :atan2,
    )
    @eval @dep_vectorize_2arg Number $f
end
# base/fastmath.jl
for f in (:pow_fast, :atan2_fast, :hypot_fast, :max_fast, :min_fast, :minmax_fast)
    eval(FastMath, :(Base.@dep_vectorize_2arg Number $f))
end
for f in (
        :max, :min, # base/math.jl
        :copysign, :flipsign, # base/floatfuncs.jl
    )
    @eval @dep_vectorize_2arg Real $f
end

# Deprecate @vectorize_1arg and @vectorize_2arg themselves
macro vectorize_1arg(S,f)
    depwarn(string("`@vectorize_1arg` is deprecated in favor of compact broadcast syntax. ",
        "Instead of `@vectorize_1arg`'ing function `f` and calling `f(arg)`, call `f.(arg)`."),
        :vectorize_1arg)
    quote
        @dep_vectorize_1arg($(esc(S)),$(esc(f)))
    end
end
macro vectorize_2arg(S,f)
    depwarn(string("`@vectorize_2arg` is deprecated in favor of compact broadcast syntax. ",
        "Instead of `@vectorize_2arg`'ing function `f` and calling `f(arg1, arg2)`, call ",
        "`f.(arg1,arg2)`. "), :vectorize_2arg)
    quote
        @dep_vectorize_2arg($(esc(S)),$(esc(f)))
    end
end
export @vectorize_1arg, @vectorize_2arg

# Devectorize manually vectorized abs methods in favor of compact broadcast syntax
@deprecate abs(f::Base.Pkg.Resolve.MaxSum.Field) abs.(f)
@deprecate abs(B::BitArray) abs.(B)
@deprecate abs(M::Bidiagonal) abs.(M)
@deprecate abs(D::Diagonal) abs.(D)
@deprecate abs(M::Tridiagonal) abs.(M)
@deprecate abs(M::SymTridiagonal) abs.(M)
@deprecate abs(x::AbstractSparseVector) abs.(x)

# Deprecate @textmime into the Multimedia module, #18441
eval(Multimedia, :(macro textmime(mime)
    Base.depwarn(string("`@textmime \"mime\"` is deprecated; use ",
        "`Base.Multimedia.istextmime(::MIME\"mime\") = true` instead"
        ), :textmime)
    quote
        Base.Multimedia.istextmime(::MIME{$(Meta.quot(Symbol(mime)))}) = true
    end
end))

@deprecate ipermutedims(A::AbstractArray,p) permutedims(A, invperm(p))

# 18696
function ($)(x, y)
    depwarn("`x \$ y` is deprecated.  use `xor(x, y)` or `x ⊻ y` instead.", :$)
    xor(x, y)
end
export $

@deprecate is (===)

@deprecate_binding Filter    Iterators.Filter
@deprecate_binding Zip       Iterators.Zip
@deprecate filter(flt, itr)  Iterators.filter(flt, itr)
@deprecate_binding rest      Iterators.rest
@deprecate_binding countfrom Iterators.countfrom
@deprecate_binding take      Iterators.take
@deprecate_binding drop      Iterators.drop
@deprecate_binding cycle     Iterators.cycle
@deprecate_binding repeated  Iterators.repeated

# promote_op method where the operator is also a type
function promote_op(op::Type, Ts::Type...)
    depwarn("promote_op(op::Type, ::Type...) is deprecated as it is no " *
            "longer needed in Base. If you need its functionality, consider " *
            "defining it locally.", :promote_op)
    if isdefined(Core, :Inference)
        return Core.Inference.return_type(op, Tuple{Ts...})
    end
    return op
end

# NOTE: Deprecation of Channel{T}() is implemented in channels.jl.
# To be removed from there when 0.6 deprecations are removed.

# Not exported, but probably better to have deprecations anyway
function reduced_dims(::Tuple{}, d::Int)
    d < 1 && throw(ArgumentError("dimension must be ≥ 1, got $d"))
    ()
end
reduced_dims(::Tuple{}, region) = ()
function reduced_dims(dims::Dims, region)
    Base.depwarn("`reduced_dims` is deprecated for Dims-tuples; pass `indices` to `reduced_indices` instead", :reduced_dims)
    map(last, reduced_indices(map(OneTo, dims), region))
end

function reduced_dims0(::Tuple{}, d::Int)
    d < 1 && throw(ArgumentError("dimension must be ≥ 1, got $d"))
    ()
end
reduced_dims0(::Tuple{}, region) = ()
function reduced_dims0(dims::Dims, region)
    Base.depwarn("`reduced_dims0` is deprecated for Dims-tuples; pass `indices` to `reduced_indices0` instead", :reduced_dims0)
    map(last, reduced_indices0(map(OneTo, dims), region))
end

function reduced_dims(a::AbstractArray, region)
    Base.depwarn("`reduced_dims` is deprecated in favor of `reduced_indices`", :reduced_dims)
    to_shape(reduced_indices(a, region))  # to_shape keeps the return-type consistent, when it's possible to do so
end

function reduced_dims0(a::AbstractArray, region)
    Base.depwarn("`reduced_dims0` is deprecated in favor of `reduced_indices0`", :reduced_dims)
    to_shape(reduced_indices0(a, region))
end

# #18218
eval(Base.LinAlg, quote
    function arithtype(T)
        Base.depwarn(string("arithtype is now deprecated. If you were using it inside a ",
            "promote_op call, use promote_op(LinAlg.matprod, Ts...) instead. Otherwise, ",
            "if you need its functionality, consider defining it locally."),
            :arithtype)
        T
    end
    function arithtype(::Type{Bool})
        Base.depwarn(string("arithtype is now deprecated. If you were using it inside a ",
            "promote_op call, use promote_op(LinAlg.matprod, Ts...) instead. Otherwise, ",
            "if you need its functionality, consider defining it locally."),
            :arithtype)
        Int
    end
end)

# #19246
@deprecate den denominator
@deprecate num numerator

Filesystem.stop_watching(stream::Filesystem._FDWatcher) = depwarn("stop_watching(::_FDWatcher) should not be used", :stop_watching)

# #19088
@deprecate takebuf_array take!
@deprecate takebuf_string(b) String(take!(b))

# #19288
eval(Base.Dates, quote
    function recur{T<:TimeType}(fun::Function, dr::StepRange{T}; negate::Bool=false, limit::Int=10000)
        depwarn("Dates.recur is deprecated, use filter instead.",:recur)
        if negate
            filter(x -> !f(x), dr)
        else
            filter(f, dr)
        end
     end
     recur{T<:TimeType}(fun::Function, start::T, stop::T; step::Period=Day(1), negate::Bool=false, limit::Int=10000) = recur(fun, start:step:stop; negate=negate)
end)

# End deprecations scheduled for 0.6

max_stars_repo_name: habemus-papadum/julia

max_issues_repo_name: habemus-papadum/julia

max_forks_repo_name: habemus-papadum/julia


text:
using Test

push!(LOAD_PATH, "./src")
using YaLinearAlgebra

@testset "Vector" begin
  vᵣ = [1.0, -1.0, π, ℯ]

  @testset ":+" begin
    @test +([1, 2, 3], [4, 5, 6]) == [5, 7, 9]
    @test [1, 2, 3] + [4, 5, 6] == [5, 7, 9]

    @test vᵣ + [-1.0, 1.0, -π, -ℯ] == zeros(eltype(vᵣ), length(vᵣ))
    @test +([[1, 2], [3, 4], [5, 6], [7, 8]]) == [16, 20]
    @test +([[1, 3, 2] for _ ∈ 1:3]) == [3, 9, 6]
  end

  @testset ":-" begin
    @test -([1, 2, 3], [4, 5, 6]) == [-3, -3, -3]
    @test [1, 2, 3] - [4, 5, 6] == [-3, -3, -3]
    @test vᵣ - [-1.0, 1.0, -π, -ℯ] == [2.0, -2.0, 2π, 2ℯ]
  end

  @testset ":*" begin
    @test *(2, [1, 2, 3]) == [2, 4, 6]
    @test *(2, [1, 2, 3]) == *([1, 2, 3], 2)
    @test 2 * [1, 2, 3] == [1, 2, 3] * 2  ==  [2, 4, 6]
  end

  @testset "μ" begin
    @test  μ([[1, 2], [3, 4], [5, 6]]) == [3., 4.]
    @test  μ([[1, 2, 1, 2], [3, 4, 3, 4], [5, 6, 5, 6]]) == [3., 4., 3., 4.]
  end

  @testset "dot, sum, norm, distance" begin
    @test dot([1, 2, 3], [4, 5, 6]) == 32

    @test sum_of_square([1, 2, 3]) == 14
    @test sum_of_square([4, 5, 6]) == 77

    @test norm([3, 4]) == 5
    @test norm([1, 0, 2]) ≈ √5

    @test distance([2, 6, 7, 7, 5, 13, 14, 17, 11, 8],

                   [3, 5, 5, 3, 7, 12, 13, 19, 22, 7]) ≈ 12.409673645990857
  end
end

max_stars_repo_path: Data Science From Scratch/test/ya_linear_algebra.jl

max_stars_repo_name: pascal-p/julia-notebooks

max_issues_repo_name: pascal-p/julia-notebooks

max_forks_repo_name: pascal-p/julia-notebooks


text:
#! /usr/bin/julia

# Rosetta Code, Compare a list of strings

function Base.isequal(a::AbstractArray)
    1 < length(a) || return true
    x = a[1]
    for y in a[2:end]
        x == y || return false
    end
    return true
end

function Base.isless(a::AbstractArray)
    1 < length(a) || return true
    for i in 2:length(a)
        a[i-1] < a[i] || return false
    end
    return true
end

tests = {["RC", "RC", "RC"],
         ["RC", "RC", "Rc"],
         ["RA", "RB", "RC"],
         ["RC"],
         ASCIIString[],
         ones(Int64, 4),
         1:4}

for a in tests
    println("\nTesting a = ", a)
    res = isequal(a) ? "are" : "are not"
    println(@sprintf "    The elements of a %s equal." res)
    res = isless(a) ? "are" : "are not"
    println(@sprintf "    The elements of a %s strictly increasing." res)
end
println()

max_stars_repo_name: MichaeLeroy/rosetta-code

max_issues_repo_name: MichaeLeroy/rosetta-code

max_forks_repo_name: MichaeLeroy/rosetta-code