text:
# Shark: Chess Constants
const WHITE  = UInt8(1)      # 0000 0001
const BLACK  = UInt8(1) << 1 # 0000 0010
const PAWN   = UInt8(1) << 2 # 0000 0100
const KNIGHT = UInt8(1) << 3 # 0000 1000
const BISHOP = UInt8(1) << 4 # 0001 0000
const ROOK   = UInt8(1) << 5 # 0010 0000
const QUEEN  = UInt8(1) << 6 # 0100 0000
const KING   = UInt8(1) << 7 # 1000 0000

# Off Board and No Piece
const OFF  = UInt8(252) # 1111 1100
const NONE = UInt8(0)   # 0000 0000

# Pieces → COLOR | CLASS
const WP, BP = WHITE | PAWN,   BLACK | PAWN
const WN, BN = WHITE | KNIGHT, BLACK | KNIGHT
const WB, BB = WHITE | BISHOP, BLACK | BISHOP
const WR, BR = WHITE | ROOK,   BLACK | ROOK
const WQ, BQ = WHITE | QUEEN,  BLACK | QUEEN
const WK, BK = WHITE | KING,   BLACK | KING

# Unicode Representation
const PIECE = Dict{UInt8, Char}(
    WP => '\u2659', BP => '\u265F', # Pawn   ♙ | ♟
    WN => '\u2658', BN => '\u265E', # Knight ♘ | ♞
    WB => '\u2657', BB => '\u265D', # Bishop ♗ | ♝
    WR => '\u2656', BR => '\u265C', # Rook   ♖ | ♜
    WQ => '\u2655', BQ => '\u265B', # Queen  ♕ | ♛
    WK => '\u2654', BK => '\u265A'  # King   ♔ | ♚
)

# Piece Move Offsets
const U, D, L, R = Int8(-10), Int8(10), Int8(-1), Int8(1)
const OFFSETS = Dict{UInt8, Tuple{Int8, Vararg}}(
    # White Pieces
    WP => (U, U+U, U+L, U+R),
    WN => (U+U+R, U+R+R, D+R+R, D+D+R, D+D+L, D+L+L, U+L+L, U+U+L),
    WB => (U+R, D+R, D+L, U+L),
    WR => (U, D, L, R),
    WQ => (U, D, L, R, U+R, D+R, D+L, U+L),
    WK => (U, D, L, R, U+R, D+R, D+L, U+L),
    # Black Pieces
    BP => (D, D+D, D+L, D+R),
    BN => (U+U+R, U+R+R, D+R+R, D+D+R, D+D+L, D+L+L, U+L+L, U+U+L),
    BB => (U+R, D+R, D+L, U+L),
    BR => (U, D, L, R),
    BQ => (U, D, L, R, U+R, D+R, D+L, U+L),
    BK => (U, D, L, R, U+R, D+R, D+L, U+L)
)

# Mailbox 12x10 Board Representation
const A1, A2, A8 = Int8(92), Int8(82), Int8(22)
const H1, H7, H8 = Int8(99), Int8(39), Int8(29)
const BOARD = "          " * #       A B C D E F G H         1 - 10
              "          " * #                              11 - 20
              " rnbqkbnr " * #   8   r n b q k b n r   8    21 - 30
              " pppppppp " * #   7   p p p p p p p p   7    31 - 40
              " ........ " * #   6   . . . . . . . .   6    41 - 50
              " ........ " * #   5   . . . . . . . .   5    51 - 60
              " ........ " * #   4   . . . . . . . .   4    61 - 70
              " ........ " * #   3   . . . . . . . .   3    71 - 80
              " PPPPPPPP " * #   2   P P P P P P P P   2    81 - 90
              " RNBQKBNR " * #   1   R N B Q K B N R   1    91 - 100
              "          " * #                             101 - 110
              "          "   #       A B C D E F G H       111 - 120

# Piece Values
const VALUE = Dict{UInt8, Int}(
    WP => 100,   BP => 100,   # Pawn   ♙ | ♟ = 100
    WN => 300,   BN => 300,   # Knight ♘ | ♞ = ♙♙♙
    WB => 300,   BB => 300,   # Bishop ♗ | ♝ = ♙♙♙
    WR => 500,   BR => 500,   # Rook   ♖ | ♜ = ♙♙♙♙♙
    WQ => 900,   BQ => 900,   # Queen  ♕ | ♛ = ♙♙♙♙♙♙♙♙♙
    WK => 50000, BK => 50000, # King   ♔ | ♚ = ~Infinity
)

# TODO: Add Piece Heuristics

# Position Heuristics
const POSITION = Dict{UInt8, Array{Int, 1}}(
    # White Pieces
    WP => VALUE[WP] .+ zeros(120),
    WN => VALUE[WN] .+ zeros(120),
    WB => VALUE[WB] .+ zeros(120),
    WR => VALUE[WR] .+ zeros(120),
    WQ => VALUE[WQ] .+ zeros(120),
    WK => VALUE[WK] .+ zeros(120),
    # Black Pieces
    BP => VALUE[BP] .+ zeros(120),
    BN => VALUE[BN] .+ zeros(120),
    BB => VALUE[BB] .+ zeros(120),
    BR => VALUE[BR] .+ zeros(120),
    BQ => VALUE[BQ] .+ zeros(120),
    BK => VALUE[BK] .+ zeros(120)
)

max_stars_repo_name: Joshua-Robison/Shark

max_issues_repo_name: Joshua-Robison/Shark

max_forks_repo_name: Joshua-Robison/Shark


text:
# License for this file: MIT (expat)
# Copyright 2017-2021, DLR Institute of System Dynamics and Control

# ToDo:
# MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently
# reuses the earlier instance.  In a future version, a new instance will always be created and returned.
# Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.
#
# Description how to get rid of the warning:
# https://stackoverflow.com/questions/46933824/matplotlib-adding-an-axes-using-the-same-arguments-as-a-previous-axes#

module ModiaPlot_PyPlot

# It seems that rcParams settings has only an effect, when set on PyPlot in Main
import ModiaResult
import Measurements
import MonteCarloMeasurements

# Determine whether pmean, pmaximum, pminimum is available (MonteCarlMeasurements, version >= 1.0)
const pfunctionsDefined = isdefined(MonteCarloMeasurements, :pmean)

using  Unitful

import PyCall
import PyPlot

export plot, showFigure, saveFigure, closeFigure, closeAllFigures

set_matplotlib_rcParams!(args...) =
   merge!(PyCall.PyDict(PyPlot.matplotlib."rcParams"), Dict(args...))

include("$(ModiaResult.path)/src/plot.jl")

function plotOneSignal(xsig, ysig, ysigType, label, MonteCarloAsArea)
    xsig2 = ustrip.(xsig)
    ysig2 = ustrip.(ysig)
	if typeof(ysig2[1]) <: Measurements.Measurement
		# Plot mean value signal
		xsig_mean = Measurements.value.(xsig2)
		ysig_mean = Measurements.value.(ysig2)
		curve = PyPlot.plot(xsig_mean, ysig_mean, label=label)

		# Plot area of uncertainty around mean value signal (use the same color, but transparent)
		color = PyPlot.matplotlib.lines.Line2D.get_color(curve[1])
		rgba  = PyPlot.matplotlib.colors.to_rgba(color)
		rgba2 = (rgba[1], rgba[2], rgba[3], 0.2)
		ysig_u   = Measurements.uncertainty.(ysig2)
		ysig_max = ysig_mean + ysig_u
		ysig_min = ysig_mean - ysig_u
		PyPlot.fill_between(xsig_mean, ysig_min, ysig_max, color=rgba2)

    elseif typeof(ysig2[1]) <: MonteCarloMeasurements.StaticParticles ||
           typeof(ysig2[1]) <: MonteCarloMeasurements.Particles
		# Plot mean value signal
        if pfunctionsDefined
            # MonteCarlMeasurements, version >= 1.0
            xsig_mean = MonteCarloMeasurements.pmean.(xsig2)
            ysig_mean = MonteCarloMeasurements.pmean.(ysig2)
        else
            # MonteCarloMeasurements, version < 1.0
            xsig_mean = MonteCarloMeasurements.mean.(xsig2)
            ysig_mean = MonteCarloMeasurements.mean.(ysig2)
        end
        xsig_mean = ustrip.(xsig_mean)
        ysig_mean = ustrip.(ysig_mean)
		curve = PyPlot.plot(xsig_mean, ysig_mean, label=label)
        color = PyPlot.matplotlib.lines.Line2D.get_color(curve[1])
        rgba  = PyPlot.matplotlib.colors.to_rgba(color)

        if MonteCarloAsArea
            # Plot area of uncertainty around mean value signal (use the same color, but transparent)
    		rgba2 = (rgba[1], rgba[2], rgba[3], 0.2)
            if pfunctionsDefined
                # MonteCarlMeasurements, version >= 1.0
                ysig_max = MonteCarloMeasurements.pmaximum.(ysig2)
                ysig_min = MonteCarloMeasurements.pminimum.(ysig2)
            else
                # MonteCarloMeasurements, version < 1.0
                ysig_max = MonteCarloMeasurements.maximum.(ysig2)
                ysig_min = MonteCarloMeasurements.minimum.(ysig2)
            end
            ysig_max = ustrip.(ysig_max)
            ysig_min = ustrip.(ysig_min)
    		PyPlot.fill_between(xsig_mean, ysig_min, ysig_max, color=rgba2)
        else
            # Plot all particle signals (use the same color, but transparent)
    		rgba2 = (rgba[1], rgba[2], rgba[3], 0.1)
            value = ysig[1].particles
            ysig3 = zeros(eltype(value), length(xsig))
            for j in 1:length(value)
                for i in eachindex(ysig)
                    ysig3[i] = ysig[i].particles[j]
                end
                ysig3 = ustrip.(ysig3)
                PyPlot.plot(xsig, ysig3, color=rgba2)
            end
        end

	else
        if typeof(xsig2[1]) <: Measurements.Measurement
            xsig2 = Measurements.value.(xsig2)
        elseif typeof(xsig2[1]) <: MonteCarloMeasurements.StaticParticles ||
               typeof(xsig2[1]) <: MonteCarloMeasurements.Particles
            if pfunctionsDefined
                # MonteCarlMeasurements, version >= 1.0
                xsig2 = MonteCarloMeasurements.pmean.(xsig2)
            else
                # MonteCarlMeasurements, version < 1.0
                xsig2 = MonteCarloMeasurements.mean.(xsig2)
            end
            xsig2 = ustrip.(xsig2)
        end
        if ysigType == ModiaResult.Continuous
            PyPlot.plot(xsig2, ysig2, label=label)
        else # ModiaResult.Clocked
            PyPlot.plot(xsig2, ysig2, ".", label=label)
        end
	end
end

"""
    addPlot(names, result, grid, xLabel, xAxis)

Add the time series of one name (if names is one symbol/string) or with
several names (if names is a tuple of symbols/strings) to the current diagram
"""
function addPlot(collectionOfNames::Tuple, result, grid::Bool, xLabel::Bool, xAxis, prefix::AbstractString, reuse::Bool, maxLegend::Integer, MonteCarloAsArea::Bool)
    xsigLegend = ""
    nLegend = 0

    for name in collectionOfNames
        name2 = string(name)
        (xsig, xsigLegend, ysig, ysigLegend, ysigType) = ModiaResult.getPlotSignal(result, name2; xsigName = xAxis)
        if !isnothing(xsig)
            nLegend = nLegend + length(ysigLegend)
            if ndims(ysig) == 1
				plotOneSignal(xsig, ysig, ysigType, prefix*ysigLegend[1], MonteCarloAsArea)
            else
                for i = 1:size(ysig,2)
					plotOneSignal(xsig, ysig[:,i], ysigType, prefix*ysigLegend[i], MonteCarloAsArea)
                end
            end
        end
    end

    PyPlot.grid(grid)
    if nLegend <= maxLegend
       PyPlot.legend()
    end

    if xLabel && !reuse && xsigLegend !== nothing
        PyPlot.xlabel(xsigLegend)
    end
end

addPlot(name::AbstractString, args...) = addPlot((name,)        , args...)
addPlot(name::Symbol        , args...) = addPlot((string(name),), args...)

#--------------------------- Plot function
function plot(result, names::AbstractMatrix; heading::AbstractString="", grid::Bool=true, xAxis=nothing,
              figure::Int=1, prefix::AbstractString="", reuse::Bool=false, maxLegend::Integer=10,
              minXaxisTickLabels::Bool=false, MonteCarloAsArea=false)

    set_matplotlib_rcParams!("axes.formatter.limits" => [-3,4],
                             "font.size"        => 8.0,
                             "lines.linewidth"  => 1.0,
                             "grid.linewidth"   => 0.5,
                             "axes.grid"        => true,
                             "axes.titlesize"   => "medium",
                             "figure.titlesize" => "medium")

    PyPlot.pygui(true) # Use separate plot windows (no inline plots)

    if isnothing(result)
        @info "The call of ModiaPlot.plot(result, ...) is ignored, since the first argument is nothing."
        return
    end
    xAxis2 = isnothing(xAxis) ? xAxis : string(xAxis)
    PyPlot.figure(figure)
    if !reuse
       PyPlot.clf()
    end
    heading2 = ModiaResult.getHeading(result, heading)
    (nrow, ncol) = size(names)

    # Add signals
    k = 1
    for i = 1:nrow
        xLabel = i == nrow
        for j = 1:ncol
            ax = PyPlot.subplot(nrow, ncol, k)
            if minXaxisTickLabels && !xLabel
                # Remove xaxis tick labels, if not the last row
                ax.set_xticklabels([])
            end
            addPlot(names[i,j], result, grid, xLabel, xAxis2, prefix, reuse, maxLegend, MonteCarloAsArea)
            k = k + 1
            if ncol == 1 && i == 1 && heading2 != "" && !reuse
                PyPlot.title(heading2)
            end
        end
    end

    # Add overall heading in case of a matrix of diagrams (ncol > 1)
    if ncol > 1 && heading2 != "" && !reuse
        PyPlot.suptitle(heading2)
    end
end

showFigure(figure::Int) = nothing

function saveFigure(figureNumber::Int, fileName)::Nothing
    fullFileName = joinpath(pwd(), fileName)
    println("... save plot in file: \"$fullFileName\"")
    PyPlot.figure(figureNumber)
    PyPlot.savefig(fileName)
    return nothing
end

closeFigure(figure::Int) = PyPlot.close(figure)

"""
    closeAllFigures()

Close all figures.
"""
closeAllFigures() = PyPlot.close("all")

end

ext: jl


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

using Markdown
using InteractiveUtils

# ╔═╡ c10d4a60-60ba-11ec-08bd-515c970644fa
md"""
# String operators
"""

# ╔═╡ 0c8e328c-9021-48a6-854f-77d3a6259e6f
md"""
This is a notebook about Strings in Julia. All information you'll find here is taken from the [official julia documentation](https://docs.julialang.org/en/v1/manual/strings/).
"""

# ╔═╡ 95e9bd04-8201-433e-b040-4b59f83210a8
md"""
## Characters

From the official Julia documentation:

> Strings are finite sequences of characters.

A character is defined using `'`, for example:
"""

# ╔═╡ 1aae74e9-75d5-4f0e-913a-ce38910500fe
a = 'a'

# ╔═╡ 1c5c5a16-d898-461e-a25c-43d6c4a762ba
md"""
Julia manages Unicode characters so you can use fun characters such as:
"""

# ╔═╡ e68679b6-30b5-4829-bff1-5e67e7c7e123
α = 'α'

# ╔═╡ 5d69e587-51c4-4eaf-baf5-6b319347231c
md"""
Or even emojis:
"""

# ╔═╡ 8bf9f202-0751-4554-847e-17dccaa27ae4
smiley = '😀'

# ╔═╡ 3976fd93-9a0f-4473-8412-519f15611c94
md"""
## Define a string

A String is defined using `"`:
"""

# ╔═╡ 5a84a6f9-c633-43cc-87d1-a4d427fd0fa9
my_string = "This is a string."

# ╔═╡ d99a8e6e-e855-47e5-b01d-8fcd0eb3e653
md"""
Multilines string can be declared as:
"""

# ╔═╡ 2cef20b8-3780-451c-95c5-d8f8a308df70
my_long_string = """This is a
longer
string
on several
lines
"""

# ╔═╡ 81ec6f7b-4011-43cb-9e07-1d307330d403
md"""
Or eventually using `\n` to separate new lines on a single line:
"""

# ╔═╡ ba82bfe2-0b3d-4fdb-a7bb-9186c6f53dc2
my_string_2 = "This is a string \nmultiline string on a single line."

# ╔═╡ 88f15430-fd0d-4775-aae7-220ffdc774b2
md"""
The advantage of using `\"\"\"` is that you can use `"` inside them:
"""

# ╔═╡ a2f51e13-d43c-460c-a000-3c26d524c54c
my_string_3 = """This is a string using "quotes" inside."""

# ╔═╡ 0a5e4a18-f40f-487d-afb7-f95e56b124b6
md"""
Another way to use special characters like `"` in a string is to escape it. To escape a character you can use `\`:
"""

# ╔═╡ 1a0e6e06-dbf4-46dd-8221-ef66754d3d9c
my_string_3_2 = "This is a string using \"quotes\" inside."

# ╔═╡ 5f85c0c8-79f8-4ce2-957f-e1e90654d4c1
md"""
Both are the same:
"""

# ╔═╡ 5083a9bb-9642-44fa-9bf9-786edc6961ed
my_string_3 == my_string_3_2

# ╔═╡ ca54b446-80f6-42e3-b47b-bbd15c38da9d
md"""
## Indexing

The fun thing about strings is that it is just a sequence of characters, so we can index into it to get the characters. For example to get the first character of out string:
"""

# ╔═╡ 13bfcbb8-0b12-4a5a-942a-e70c7241b39c
my_string_3[1]

# ╔═╡ aff886a0-afe0-415b-8a04-7f68162dc0f8
md"""
Or the last one:
"""

# ╔═╡ 4f83b903-7932-4955-a0d7-665ecb8f2af4
my_string_3[end]

# ╔═╡ 6b074341-9a12-496c-af58-691854436641
md"""
We can think of a String as a vector of characters, so functions like `length` work:
"""

# ╔═╡ f32a212b-39e9-4c30-8bc8-d66fb69e1a86
length(my_string_3)

# ╔═╡ b3b10550-a55f-46f1-acfa-2dcc99945e86
md"""
We can also get a sub-string from the string by indexing using a sequence:
"""

# ╔═╡ 1cae1754-c3d1-42bd-ab53-bb77be8b27e4
first_word = my_string_3[1:4]

# ╔═╡ 537b2951-e07d-4a71-839c-9f46bc96141c
typeof(first_word)

# ╔═╡ 74607235-ae72-4b2d-94eb-9418245ebe6b
md"""
We can also get one character as a 1-character string:
"""

# ╔═╡ 39c565e4-aa75-4f68-a4a6-52941c4c58f5
first_letter_as_string = my_string_3[1:1]

# ╔═╡ c71ac057-ba81-4732-94e7-9e47ea6e543a
typeof(first_letter_as_string)

# ╔═╡ 651f80f8-6df0-4afd-804f-94d3ea388e7f
md"""
## Interpolation
"""

# ╔═╡ ada9fd27-9ca4-4925-a2c8-3cdbbc0649fe
md"""
We can use values from variables when creating a string using `$`:
"""

# ╔═╡ 74f47a35-0f91-413a-b567-5fb49f1f45a3
x = 1; y = 2

# ╔═╡ edd6cdb6-90ac-42f6-b2dd-9e4b4b9fc24b
"x is equal to $x and y is equal to $y"

# ╔═╡ 7bf49b1f-2c09-4f8a-a35b-88ef7dc9cf46
md"""
`$` is a function, so you can pass more using parenthesis:
"""

# ╔═╡ 238d5b12-7bdc-4084-ac09-6818055b0468
"x+y=$(x+y)"

# ╔═╡ da11e225-4524-4509-a6d3-9d87a4faa784
md"""
For that reason, if you need to use \$ in a string, you must escape it as seen before, using `\`:
"""

# ╔═╡ e44984e5-49ba-443a-821c-dd163523c890
"using \$ in a sentence, and also using it as a function: x is equal to $x"

# ╔═╡ fcfacddd-5e41-429a-863d-a7029b3e29a9
md"""
!!! note
	The escape character `\` is visible when printing in Pluto, but would not be visible in a print to the user. For example you see the sentence written in markdown above is using an escape character before `$` and it just displays the dollar sign, not `\`.
"""

# ╔═╡ b577f240-4d86-4ad0-aa80-8ae461f2339c
md"""
## Concatenation
"""

# ╔═╡ afa56a1f-c011-49c2-83a7-283119cdb1a3
md"""
We can concatenate two strings using `string`:
"""

# ╔═╡ ea9c9b69-d346-4397-94cf-613fcf839565
string("First string", ", second string")

# ╔═╡ d46d8c2a-9d2e-4c13-9716-15a9dd1034c6
md"""
Or using `*` as a shortcut:
"""

# ╔═╡ 333062b7-988e-4d71-820a-a0c9d9e8082b
"First string" * ", second string"

# ╔═╡ ca460e95-26ea-4acf-bff4-b965d5f2736d
md"""
You can also use join to concatenate a string or a vector of strings with another string, *e.g.*:
"""

# ╔═╡ 332eff01-989f-487e-a393-e170be5d2d26
join(["First string", "second string"], ", ")

# ╔═╡ ea0c2c6a-5d37-417c-9a46-2989f43431cb
md"""
The vector of strings is concatenated together using ", " as a separator.
"""

# ╔═╡ 5b674596-8fc6-46a5-8f90-057a398f405d
md"""
## Comparison

We can compare strings with the usual operators:

- `==` for equality comparison
"""

# ╔═╡ 0b2f4857-6760-4b31-8b42-18c542e5e23b
"a string" == "another string"

# ╔═╡ 1d2efe68-18d5-4cce-bfa2-3a851cd4b697
"a string" != "another string"

# ╔═╡ 3dae3bf7-98c8-4269-8d4d-2c0c7bc2ca30
md"""
- `<`, `>`, `<=` and `>=`:
"""

# ╔═╡ b3ded341-ce60-4173-bc1c-4faaa4bc7d61
"a" < "z"

# ╔═╡ 69fbf0e6-90e4-4699-8c54-69fa13ff8da7
"a" <= "b"

# ╔═╡ 045f1583-d6e4-4473-b3a2-201778182791
"ab" > "aa"

# ╔═╡ 8cbfe0fc-6ca2-47b2-90fc-abd6fba78f86
"aab" >= "aaa"

# ╔═╡ 0627bfe1-947f-483d-97fd-1ed09afb7195
md"""
## Search

We can search if a character is in another one using different functions:
"""

# ╔═╡ a9d59caf-1466-4064-815f-13baf47b62b0
findfirst(isequal('o'), "school")

# ╔═╡ a7164dee-5b1a-4794-8dce-2d326711b761
findlast(isequal('o'), "school")

# ╔═╡ f74ecac0-fdbe-4852-8dc0-4ae755535853
findall(isequal('o'), "school")

# ╔═╡ 71e9fea8-0b3f-4fc5-9ee7-6e9d8860d05e
md"""
We can use the same functions to know if a string is in another:
"""

# ╔═╡ 1eba7dd1-c541-4362-a03a-2972502fca9a
findfirst("is", "School is good!")

# ╔═╡ 1d603329-b127-4707-aebd-efe2c58261af
md"""
Or test whether a string occurs in a another:
"""

# ╔═╡ 36eaac1d-898c-4ed3-8fc5-14468dce1074
occursin("cat", "Oggy is my cat.")

# ╔═╡ 807b0051-c8d9-4236-8a3d-36ebdde77314
md"""
## Replace

We can replace words in a string using `replace`:
"""

# ╔═╡ 683b87d9-f733-4f51-8dc6-516d7e6beef7
replace("Oggy is my cat.", "cat" => "wonderfull cat")

# ╔═╡ 2b184027-f575-4fe6-a8ba-3b3c74c05b1e
md"""
`replace` takes a string to modify as the first argument, and a Pair as the second argument. The Pair is formatted as follows: `"string to replace" => "string that will replace the first one"`.
"""

# ╔═╡ 0c93a4dc-d993-48f5-b67f-6cb7cece5366
md"""
We can also replace single characters if needed:
"""

# ╔═╡ c2f8c53f-3e5d-4c35-8618-d1b3af41a414
replace("Oggy is my cat.", 't' => 'r')

# ╔═╡ b81f16cb-7263-4c42-b25a-9500c67099f0
md"""
## Regular expressions

Regular expressions are used to search patterns in strings with some rules.

A rule can be something such as "starting with", "ending with", "containing = as the third character, followed by a blank space and then an integer".

A regular expression is declared itself as a string, preffixed with an `r`:
"""

# ╔═╡ acb9ceeb-99a1-450b-a0f7-1d96f1d8c115
typeof(r"test")

# ╔═╡ e6753dc1-9650-44cb-98c9-5ef17b4ba890
md"""
Regex means **Reg**ular **ex**pression.

For example you could be interested knowing if a string starts with an O In this case you can use `^`:
"""

# ╔═╡ feec3956-75d5-4fb5-b48d-b155641b7c50
occursin(r"^O", "Oggy is my cat.")

# ╔═╡ 435a996f-6409-4d63-a7dc-0330a37a1ae3
md"""
Here the regular expression can be translated to "Is my string starting with O".

If we want to know if it ends with something, we cans use $ as a suffix:

"""

# ╔═╡ fa1070aa-56e1-4a9c-802a-229712533b49
occursin(r"cat.$", "Oggy is my cat.")

# ╔═╡ 84a92180-216e-455d-b79a-240d43d31573
md"""
Now here we made a mistake without realising it. How? Look at the following:
"""

# ╔═╡ 2fe3e037-cccf-4456-bb49-90f0d31ed5ed
occursin(r"cat.$", "Oggy is my cats")

# ╔═╡ fa0c758c-e6ab-40fc-ac0b-8d49431ca846
md"""
It returns `true` again, but our last character is a `.`, not an s!

This is because `.` is a special character in regular expression that is used to match **any** character.

Here is a little list of the most important special characters:

- `^` starts with (used as a prefix, *e.g.*: `r"^a"` means starts with "a")
- `$` ends with (used as a suffix, *e.g.*: `r"a$"` means ends with "a")
- `*` appears 0 or more times (*e.g.*: `r"a*"` has "a" zero or more times)
- `+` appears 1 or more times (*e.g.*: `r"a+"` has "a" one or more times)
- `{n}` appears n time (*e.g.*: `r"a{2}"` has "a" two times)
- `[alpha]` alphabetic character
- `[alnum]` alphanumeric character
- `[blank]` space or tab
- `[x-y]` range

"""

# ╔═╡ 6ca8ce2e-92f8-4731-bfa4-26ce1a18112f
occursin(r"^b", "banana") # starts with "b"

# ╔═╡ c3dfed90-9ed5-4595-8f82-62e4d4c0b8f3
occursin(r"5$", "My home adress is 5") # ends with 5

# ╔═╡ a6918fd1-dd29-416e-901e-f78de4b84e8c
occursin(r"c*", "banana") # has "c" 0 or more times (0 times here)

# ╔═╡ b306c22e-09f8-42bc-8a7a-a65eadee2c6f
occursin(r"c+", "banana") # has "c" 1 or more times

# ╔═╡ 8c7393da-04ac-4e8e-9b02-d09de338caad
occursin(r"a{3}", "banana") # has "a" three times in a row (not here!)

# ╔═╡ 55487736-ca4b-4052-b685-273af0c98621
occursin(r"a[[:alpha:]]c", "abc") # has "a", an alphabetical letter and then a "c"

# ╔═╡ 57c43dc9-a3f2-457e-87ea-ebf91136b3c5
occursin(r"a[[:alnum:]]c", "abc") # has "a", an alphanumeric character and then "c"

# ╔═╡ dc4911d3-a27b-469c-a55a-af74d4ffb8e9
occursin(r"a[[:blank:]]", "a ") # has "a" and then a blank

# ╔═╡ 0b5275c7-640f-43a9-97ad-c6cab8e6a770
occursin(r"[0-9]23", "123") # has a number between 0 and 9 and then 2 and 3

# ╔═╡ ba3dc7d8-4404-4c8e-a1be-3a77d11e1fdd
md"""
Now imagine we manage a data base of animals and their id is a string of their names and an index:
"""

# ╔═╡ 0673652a-64cc-4c7f-a5b7-97e135226b6a
string_vec = ["cat122", "bird233", "bird001", "dog001", "dog899", "error101", "101warning"]

# ╔═╡ c877e542-e8c5-4d03-9a77-1ac04823237a
md"""
If we want only the animals that have an id greater than 200, we can use a regular expression such as:
"""

# ╔═╡ af97e353-5a40-42ba-87cc-2c3c41f2e532
id_greater_than_200 = r"^[[:alpha:]]{3,4}[2-9]"

# ╔═╡ 6d03558b-e727-4136-bc16-bd282cda6b94
md"""
Which means in plain english:

We want a string that starts (`^`) with three or four (`{3,4}`) alphabetical letters (`[[:alpha:]]`) and followed by a number between 2 and 9 (`[2-9]`). We don't want any filter on the following characters.

And our results is:
"""

# ╔═╡ 759c5c8c-3ba7-43f3-93d9-f335cd5ac10c
string_vec[occursin.(id_greater_than_200, string_vec)]

# ╔═╡ 015c8c0a-907e-46d4-8d42-1e311c4d28a9
md"""
!!! note
	What happens here is that we broadcast occursin (the point after the function name: `occursin.`) because we apply the function on a vector. Then we use the output of occursin to index in our vector `string_vec`, which only returns the strings that were selected by our regular expression.
"""

# ╔═╡ fa009519-64b9-419f-9997-988ece677b02
md"""
Now we could make it more generic using this kind of regular expression instead:
"""

# ╔═╡ d50b40a0-122b-4ffd-8e6f-5ab984f24488
generic_regexp = r"^[[:alpha:]]+[2-9][0-9]{2,}"

# ╔═╡ 0e81fd9f-d41f-4cd8-ac2c-5343ad8cb0ee
md"""
which would ask for a string starting (`^`) with any number (`+`) of alphabetical letters (`[[:alpha:]]`) followed by an integer value greater that 2 (`[2-9]`) and at least two (`{2,}`) number values between 0 and 9 (at least 2 to get at least 200). This way the expression would work for any kind of animal name and index in the database, not just the ones above:
"""

# ╔═╡ 8f23a237-aa5a-4df0-8056-0f30f60b8b93
occursin(generic_regexp, "unicorn35599944455")

# ╔═╡ f110c98a-8c85-40c3-a3b6-1a5a505d2274
md"""
Yes, there are more unicorns than humans, but I don't know where they live.
"""

# ╔═╡ Cell order:
# ╟─c10d4a60-60ba-11ec-08bd-515c970644fa
# ╟─0c8e328c-9021-48a6-854f-77d3a6259e6f
# ╟─95e9bd04-8201-433e-b040-4b59f83210a8
# ╠═1aae74e9-75d5-4f0e-913a-ce38910500fe
# ╟─1c5c5a16-d898-461e-a25c-43d6c4a762ba
# ╠═e68679b6-30b5-4829-bff1-5e67e7c7e123
# ╟─5d69e587-51c4-4eaf-baf5-6b319347231c
# ╠═8bf9f202-0751-4554-847e-17dccaa27ae4
# ╟─3976fd93-9a0f-4473-8412-519f15611c94
# ╠═5a84a6f9-c633-43cc-87d1-a4d427fd0fa9
# ╟─d99a8e6e-e855-47e5-b01d-8fcd0eb3e653
# ╠═2cef20b8-3780-451c-95c5-d8f8a308df70
# ╟─81ec6f7b-4011-43cb-9e07-1d307330d403
# ╠═ba82bfe2-0b3d-4fdb-a7bb-9186c6f53dc2
# ╟─88f15430-fd0d-4775-aae7-220ffdc774b2
# ╠═a2f51e13-d43c-460c-a000-3c26d524c54c
# ╟─0a5e4a18-f40f-487d-afb7-f95e56b124b6
# ╠═1a0e6e06-dbf4-46dd-8221-ef66754d3d9c
# ╟─5f85c0c8-79f8-4ce2-957f-e1e90654d4c1
# ╠═5083a9bb-9642-44fa-9bf9-786edc6961ed
# ╟─ca54b446-80f6-42e3-b47b-bbd15c38da9d
# ╠═13bfcbb8-0b12-4a5a-942a-e70c7241b39c
# ╟─aff886a0-afe0-415b-8a04-7f68162dc0f8
# ╠═4f83b903-7932-4955-a0d7-665ecb8f2af4
# ╟─6b074341-9a12-496c-af58-691854436641
# ╠═f32a212b-39e9-4c30-8bc8-d66fb69e1a86
# ╟─b3b10550-a55f-46f1-acfa-2dcc99945e86
# ╠═1cae1754-c3d1-42bd-ab53-bb77be8b27e4
# ╠═537b2951-e07d-4a71-839c-9f46bc96141c
# ╟─74607235-ae72-4b2d-94eb-9418245ebe6b
# ╠═39c565e4-aa75-4f68-a4a6-52941c4c58f5
# ╠═c71ac057-ba81-4732-94e7-9e47ea6e543a
# ╟─651f80f8-6df0-4afd-804f-94d3ea388e7f
# ╟─ada9fd27-9ca4-4925-a2c8-3cdbbc0649fe
# ╠═74f47a35-0f91-413a-b567-5fb49f1f45a3
# ╠═edd6cdb6-90ac-42f6-b2dd-9e4b4b9fc24b
# ╟─7bf49b1f-2c09-4f8a-a35b-88ef7dc9cf46
# ╠═238d5b12-7bdc-4084-ac09-6818055b0468
# ╟─da11e225-4524-4509-a6d3-9d87a4faa784
# ╠═e44984e5-49ba-443a-821c-dd163523c890
# ╟─fcfacddd-5e41-429a-863d-a7029b3e29a9
# ╟─b577f240-4d86-4ad0-aa80-8ae461f2339c
# ╟─afa56a1f-c011-49c2-83a7-283119cdb1a3
# ╠═ea9c9b69-d346-4397-94cf-613fcf839565
# ╟─d46d8c2a-9d2e-4c13-9716-15a9dd1034c6
# ╠═333062b7-988e-4d71-820a-a0c9d9e8082b
# ╟─ca460e95-26ea-4acf-bff4-b965d5f2736d
# ╠═332eff01-989f-487e-a393-e170be5d2d26
# ╟─ea0c2c6a-5d37-417c-9a46-2989f43431cb
# ╟─5b674596-8fc6-46a5-8f90-057a398f405d
# ╠═0b2f4857-6760-4b31-8b42-18c542e5e23b
# ╠═1d2efe68-18d5-4cce-bfa2-3a851cd4b697
# ╟─3dae3bf7-98c8-4269-8d4d-2c0c7bc2ca30
# ╠═b3ded341-ce60-4173-bc1c-4faaa4bc7d61
# ╠═69fbf0e6-90e4-4699-8c54-69fa13ff8da7
# ╠═045f1583-d6e4-4473-b3a2-201778182791
# ╠═8cbfe0fc-6ca2-47b2-90fc-abd6fba78f86
# ╟─0627bfe1-947f-483d-97fd-1ed09afb7195
# ╠═a9d59caf-1466-4064-815f-13baf47b62b0
# ╠═a7164dee-5b1a-4794-8dce-2d326711b761
# ╠═f74ecac0-fdbe-4852-8dc0-4ae755535853
# ╟─71e9fea8-0b3f-4fc5-9ee7-6e9d8860d05e
# ╠═1eba7dd1-c541-4362-a03a-2972502fca9a
# ╟─1d603329-b127-4707-aebd-efe2c58261af
# ╠═36eaac1d-898c-4ed3-8fc5-14468dce1074
# ╟─807b0051-c8d9-4236-8a3d-36ebdde77314
# ╠═683b87d9-f733-4f51-8dc6-516d7e6beef7
# ╟─2b184027-f575-4fe6-a8ba-3b3c74c05b1e
# ╟─0c93a4dc-d993-48f5-b67f-6cb7cece5366
# ╠═c2f8c53f-3e5d-4c35-8618-d1b3af41a414
# ╟─b81f16cb-7263-4c42-b25a-9500c67099f0
# ╠═acb9ceeb-99a1-450b-a0f7-1d96f1d8c115
# ╟─e6753dc1-9650-44cb-98c9-5ef17b4ba890
# ╠═feec3956-75d5-4fb5-b48d-b155641b7c50
# ╟─435a996f-6409-4d63-a7dc-0330a37a1ae3
# ╠═fa1070aa-56e1-4a9c-802a-229712533b49
# ╟─84a92180-216e-455d-b79a-240d43d31573
# ╠═2fe3e037-cccf-4456-bb49-90f0d31ed5ed
# ╟─fa0c758c-e6ab-40fc-ac0b-8d49431ca846
# ╠═6ca8ce2e-92f8-4731-bfa4-26ce1a18112f
# ╠═c3dfed90-9ed5-4595-8f82-62e4d4c0b8f3
# ╠═a6918fd1-dd29-416e-901e-f78de4b84e8c
# ╠═b306c22e-09f8-42bc-8a7a-a65eadee2c6f
# ╠═8c7393da-04ac-4e8e-9b02-d09de338caad
# ╠═55487736-ca4b-4052-b685-273af0c98621
# ╠═57c43dc9-a3f2-457e-87ea-ebf91136b3c5
# ╠═dc4911d3-a27b-469c-a55a-af74d4ffb8e9
# ╠═0b5275c7-640f-43a9-97ad-c6cab8e6a770
# ╟─ba3dc7d8-4404-4c8e-a1be-3a77d11e1fdd
# ╠═0673652a-64cc-4c7f-a5b7-97e135226b6a
# ╟─c877e542-e8c5-4d03-9a77-1ac04823237a
# ╠═af97e353-5a40-42ba-87cc-2c3c41f2e532
# ╟─6d03558b-e727-4136-bc16-bd282cda6b94
# ╠═759c5c8c-3ba7-43f3-93d9-f335cd5ac10c
# ╟─015c8c0a-907e-46d4-8d42-1e311c4d28a9
# ╟─fa009519-64b9-419f-9997-988ece677b02
# ╠═d50b40a0-122b-4ffd-8e6f-5ab984f24488
# ╟─0e81fd9f-d41f-4cd8-ac2c-5343ad8cb0ee
# ╠═8f23a237-aa5a-4df0-8056-0f30f60b8b93
# ╟─f110c98a-8c85-40c3-a3b6-1a5a505d2274


text:
mutable struct NinePinSerialPort
    pins::BitArray
    function NinePinSerialPort()
        this = new()
        this.pins = BitArray(9)
    end
end

const CD = 1
const RD = 2
const TD = 3
const SG = 5
const DSR = 6
const RTS = 7
const CTS = 8

# Here we test the type's code.
port = NinePinSerialPort()
println("Port is now at defaults, which are $port")
port[CTS] = true
println("CD pin of port, which is pin $CD, is now $(port[CD])")
println("CTS pin of port, which is pin $CTS, is now $(port[CTS])")
println("port is now: $port")

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
using OVERTVerify
using LazySets
using Dates
using JLD2

function run_query(query_number, avoid_set, controller_name; threads=0)
	controller = "nnet_files/jmlr/car_"*controller_name*"_controller.nnet"
	println("Controller is: ", controller)

	query = OvertQuery(
		SimpleCar,  # problem
		controller,    # network file
		Id(),      	# last layer activation layer Id()=linear
		"MIP",     	# query solver, "MIP" or "ReluPlex"
		10,        	# ntime
		0.2,       	# dt
		-1,        	# N_overt
		)

	input_set = Hyperrectangle(low=[9.5, -4.5, 2.1, 1.5], high=[9.55, -4.45, 2.11, 1.51])
	t1 = Dates.time()
	SATii, valii, statii = symbolic_satisfiability(query, input_set, avoid_set; return_all=true, threads=threads)
	println("satii is: ", SATii)
	t2 = Dates.time()
	dt = (t2-t1)
	println("dt is $dt")

	JLD2.@save "src/examples/jmlr/data/car_satisfiability_"*string(controller_name)*"_controller_data_q"*string(query_number)*".jld2" query input_set avoid_set SATii valii statii dt

	println("satii after save is: ", SATii)
	return SATii
end

function run_car_satisfiability(; controller_name="smallest", threads=0)
	# In this example, our property is the following:
	# We want the car to reach the box [-.6, .6] [-.2,.2]
	# at SOME point in the time history
	# we will perform 4 separate queries and "AND" them together to look
	# for a point where all properties hold

	# query 1  x1 <= -0.6
	avoid_set1 = HalfSpace([1.0, 0.0, 0.0, 0.0], -0.6)
	# query 2 x1 >= 0.6  ->  -0.6 >= -x1   ->  -x1 <= -0.6
	avoid_set2 = HalfSpace([-1.0, 0.0, 0.0, 0.0], -0.6)
	# query 3  x2 <= -0.2
	avoid_set3 = HalfSpace([1.0, 0.0, 0.0, 0.0], -0.2)
	# query 4  x2 >= 0.2  aka -x2 <= -0.2
	avoid_set4 = HalfSpace([-1.0, 0.0, 0.0, 0.0], -0.2)
	avoid_sets = [avoid_set1, avoid_set2, avoid_set3, avoid_set4]

	SAT = []

	s = ["unsat", "unsat"]
	for enum = enumerate(avoid_sets)
		i, avoid_set = enum
		if ~all(s .== "sat") # possibly quit early if all of s = "sat"
			s = run_query(i, avoid_set, controller_name, threads=threads)
			# BOOKMARK: add breakpoint here to see why s isn't being pushed onto the SAT array...
			push!(SAT, s)
		else
			println("skipping property ", i, " because prior property does not hold any time.")
		end
	end

	# now we want to know when all properties hold
	all_hold = [true for _ in 1:length(SAT[1])]
	for i = 1:length(SAT)
		all_hold = all_hold .& (SAT[i] .== "unsat")
	end
	timesteps_where_properties_hold = findall(all_hold)
	if length(timesteps_where_properties_hold) > 0
		println("The property holds at timestep: ", timesteps_where_properties_hold)
	else
		println("The property does not hold.")
	end

	JLD2.@save "src/examples/jmlr/data/car_satisfiability_"*string(controller_name)*"_controller_data_final_result.jld2" SAT timesteps_where_properties_hold
end

# 0 threads means "let gurobi decide how many threads it wants"
run_car_satisfiability(controller_name=ARGS[1], threads=0)


text:
#!/usr/bin/env julia

# Copyright 2022 John T. Foster
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import assignment7
using Test

@testset "assignment7.jl" begin
    @test assignment7.add_positional_arguments(1, 2, 3.0) ≈ 6.0
    @test assignment7.add_positional_arguments(1, 2) ≈ 5.0
    @test assignment7.Σ(2, 2, 2) ≈ 6.0
    @test assignment7.Σ(2, 2) ≈ 6.0
    @test assignment7.add_keyword_arguments(a=1, b=2, c=3) ≈ 6.0
    @test assignment7.add_keyword_arguments() ≈ 6.0
    @test assignment7.add_keyword_arguments(a=1, b=2) ≈ 6.0
    f = assignment7.return_anonymous_function()
    @test f(2.0) ≈ 5.0
end


text:
mutable struct HDS <: Sampler
    target_ratio::Real
    threshold_strat::Union{ThresholdStrategy, Nothing}
    threshold::Union{Real, Nothing}
    kde_cache::Union{KDECache, Nothing}
    gamma::Union{Symbol, Real}
    function HDS(target_ratio::Real, kde_cache::Union{KDECache, Nothing}, gamma::Union{Symbol, Real}, threshold_strat::Union{ThresholdStrategy, Nothing}=nothing)
        0 <= target_ratio <= 1 || throw(ArgumentError("Invalid sampling ratio $(target_ratio)."))
        return new(target_ratio, threshold_strat, nothing, kde_cache, gamma)
    end
end

function HDS(target_ratio::Real, kde_cache::KDECache, threshold_strat::Union{ThresholdStrategy, Nothing}=nothing)
    return HDS(target_ratio, kde_cache, :precomputed, threshold_strat)
end

function HDS(target_ratio::Real, gamma::Union{Symbol, Real}, threshold_strat::Union{ThresholdStrategy, Nothing}=nothing)
    return HDS(target_ratio, nothing, gamma, threshold_strat)
end

function sample(sampler::HDS, data::DataSet, labels::Vector{Symbol})::BitArray{1}
    if sampler.kde_cache === nothing || sampler.kde_cache.data != data
        sampler.kde_cache = KDECache(data, sampler.gamma)
    end
    sampler.threshold, inlier_mask, outlier_mask = split_masks(sampler.threshold_strat,
                                                               sampler.kde_cache,
                                                               labels)
    sample_mask = inlier_mask
    target_size = round(Int, sampler.target_ratio * size(data, 2))
    d_x = kde(sampler.kde_cache, sample_mask, trues(size(data, 2)))
    while count(sample_mask) > target_size
        idx = findall(sample_mask)[findmax(d_x[sample_mask])[2]]
        sample_mask[idx] = false
        d_x -= sampler.kde_cache.K[:, idx]
    end
    sampler.threshold = any(sample_mask) ? minimum(kde(sampler.kde_cache, sample_mask, sample_mask)) : 0
    return sample_mask
end


text:
@testset "PriceLevels" begin

    min_price = UInt128(1)
    max_price = UInt128(100)

    pls = PriceLevels(max_price, min_price)
    @test size(pls) == (100,)

    @test pls.bid == 1
    @test pls.ask == 100

    insert_order!(pls, LimitOrder(UInt128(10), UInt128(10),
                                  UInt128(1), BUY, UInt128(1)))
    @test pls.bid == 10

    insert_order!(pls, LimitOrder(UInt128(11), UInt128(10),
                                  UInt128(1), SELL, UInt128(1)))
    @test pls.ask == 11

    @testset "Different Min and Max Price" begin

        min_price = UInt128(10)
        max_price = UInt128(20)
        pls = PriceLevels(max_price, min_price)
        @test size(pls) == (11,)

        insert_order!(pls, LimitOrder(UInt128(10), UInt128(10),
                                  UInt128(1), BUY, UInt128(1)))
        @test pls.bid == 10

        insert_order!(pls, LimitOrder(UInt128(20), UInt128(10),
                                  UInt128(1), SELL, UInt128(1)))
        @test pls.ask == 20
    end

end


text:
include("euler/euler.jl")
using .Grid: max_path_sum
using BenchmarkTools
BenchmarkTools.DEFAULT_PARAMETERS.samples = 100

function compute(path::String)::Int
    triangle = map(x -> parse.(Int, split(x, " ")), split(read(path, String), "\n"))
    return max_path_sum(triangle)
end

compute("problems/0067/p067_triangle.txt")

@benchmark compute("problems/0067/p067_triangle.txt")

max_stars_repo_name: Dynortice/Project-Euler

max_issues_repo_name: Dynortice/Project-Euler

max_forks_repo_name: Dynortice/Project-Euler


text:
using Documenter
using Automa

# run(`julia actions.jl`)
# run(`julia preconditions.jl`)

makedocs(
    sitename = "Automa.jl",
    modules = [Automa],
    pages = [
        "Home" => "index.md",
        "References" => "references.md"
        ],
    format = Documenter.HTML(
        prettyurls = get(ENV, "CI", nothing) == "true")
)

deploydocs(
    repo = "github.com/BioJulia/Automa.jl.git",
    target = "build",
    push_preview = true,
)


text:
# Linear Isotropic Covariance Function

"""
    LinIso <: Kernel

Isotropic linear kernel (covariance)
```math
k(x, x') = xᵀx'/ℓ²
```
with length scale ``ℓ``.
"""
mutable struct LinIso{T<:Real} <: Kernel
    "Squared length scale"
    ℓ2::T
    "Priors for kernel parameters"
    priors::Array
end

"""
Linear Isotropic Covariance Function

    LinIso(ll::T)

# Arguments
 - `ll::Real`: length scale (given on log scale)
"""
LinIso(ll::T) where T = LinIso{T}(exp(2 * ll), [])

struct LinIsoData{D} <: KernelData
    XtX::D
end

function KernelData(k::LinIso, X1::AbstractMatrix, X2::AbstractMatrix)
    XtX=X1'*X2
	if X1==X2
		LinearAlgebra.copytri!(XtX, 'U') # make sure it's symmetric
	end
    LinIsoData(XtX)
end
kernel_data_key(k::LinIso, X1::AbstractMatrix, X2::AbstractMatrix) = "LinIsoData"

_cov(lin::LinIso, xTy) = xTy ./ lin.ℓ2
function cov(lin::LinIso, x::AbstractVector, y::AbstractVector)
    K = _cov(lin, dot(x,y))
    return K
end

@inline @inbounds function cov_ij(lin::LinIso, X1::AbstractMatrix, X2::AbstractMatrix, data::LinIsoData, i::Int, j::Int, dim::Int)
    return _cov(lin, data.XtX[i, j])
end
@inline @inbounds function cov_ij(lin::LinIso, X1::AbstractMatrix, X2::AbstractMatrix, i::Int, j::Int, dim::Int)
    return _cov(lin, dot(@view(X1[:,i]), @view(X2[:,j])))
end
function cov!(cK::AbstractMatrix, lin::LinIso, X1::AbstractMatrix, X2::AbstractMatrix, data::LinIsoData)
    iℓ2 = 1/lin.ℓ2
    @inbounds @simd for I in eachindex(cK,data.XtX)
        cK[I] = data.XtX[I]*iℓ2
    end
    return cK
end

get_params(lin::LinIso{T}) where T = T[log(lin.ℓ2) / 2]
get_param_names(::LinIso) = [:ll]
num_params(lin::LinIso) = 1

function set_params!(lin::LinIso, hyp::AbstractVector)
    length(hyp) == 1 || throw(ArgumentError("Linear isotropic kernel has one parameter, received $(length(hyp))."))
    lin.ℓ2 = exp(2 * hyp[1])
end

@inline dk_dll(lin::LinIso, xTy::Real) = -2 * _cov(lin,xTy)
@inline function dKij_dθp(lin::LinIso, X1::AbstractMatrix, X2::AbstractMatrix, i::Int, j::Int, p::Int, dim::Int)
    if p==1
        return dk_dll(lin, dotij(X1,X2,i,j,dim))
    else
        return NaN
    end
end
@inline function dKij_dθp(lin::LinIso, X1::AbstractMatrix, X2::AbstractMatrix, data::LinIsoData, i::Int, j::Int, p::Int, dim::Int)
    if p==1
        return dk_dll(lin, data.XtX[i,j])
    else
        return NaN
    end
end


text:
#!~/julia

println("Julia: Hello World!")
println("This is α and Ω.")


text:
module PostgresQoL

using DataFrames, JSON, LibPQ, Tables

include("sqlqol.jl")
include("sqlcolumn.jl")
include("condition.jl")
include("createtable.jl")
include("droptable.jl")
include("insertinto.jl")
include("update.jl")
include("deletefrom.jl")
include("join.jl")
include("query.jl")
include("compoundquery.jl")

end  # module PostgresQoL


text:
module ChineseTokenizers

import Base: split, display, read, write, first, stat

using AhoCorasickAutomatons
using Pkg

export HiddenMarkovModel
using Markdown, ProgressMeter

include("HiddenMarkovModels.jl")
include("ConditionalRandomFields.jl")
include("ChineseTrees.jl")
include("cyks.jl")
include("utils.jl")

CTB_POS = Markdown.MD(Markdown.Table(Any[["CTB_POS", "PKU_POS", "summary"],
                ["NR", "", "专属名词"],
                ["NT", "", "时间"],
                ["NN", "", "其他"],
                ["PN", "", "代词"],
                ["VA", "", "形容词动词化"],
                ["VC", "", "be, not be 对应的中文"],
                ["VE", "", "have, not have 对应的中文"],
                ["VV", "", "其他"],
                ["P", "", "介词"],
                ["LC", "", "方位词"],
                ["AD", "", "副词"],
                ["DT", "", "谁的，哪一个"],
                ["CD", "", "量词"],
                ["OD", "", "序词"],
                ["M", "", "量词"],
                ["CC", "", "连词"],
                ["CS", "", "连词"],
                ["DEC", "", "的"],
                ["DEG", "", "的"],
                ["DER", "", "得"],
                ["DEV", "", "地"],
                ["AS", "", "Aspect Particle 表达英语中的进行式、完成式的词，比如（着，了，过）"],
                ["SP", "", "句子结尾词（了，吧，呢，啊，呀，吗）"],
                ["ETC", "", "等（等）"],
                ["MSP", "", "其他"],
                ["IJ", "", "句首感叹词"],
                ["ON", "", "象声词"],
                ["LB", "", "被"],
                ["SB", "", "被"],
                ["BA", "", "把"],
                ["JJ", "", "名词修饰词"],
                ["PU", "", "标点符号"],
                ["FW", "", "POS不清楚的词（不是外语词）"]], Symbol[:l, :l, :l]));
end # module


text:
# cuda20: Kernels for Array->Scalar reduction.

fp = open("cuda20.cu","w")
#using Knet: reduction_ops

# Reduction to a scalar
# CUBLAS nrm2 is extremely slow.  The following is based on code from Barret Zoph.
# Based on: http://developer.download.nvidia.com/compute/cuda/1.1-Beta/x86_website/projects/reduction/doc/reduction.pdf

function cuda20src(f, j, op, f1, v0; BLK=128, THR=128)
    sprint() do s
        for (T,F) in [("float","$(f)_32"),("double","$(f)_64")]
            print(s,
"""
__device__ void _$(F)_20_0(volatile $T *x, int i) {
//for optimizing warps
//volatile must be used as register optimization will lead to wrong answers
  $T ai, xi;
  ai=x[i]; xi=x[i+32]; x[i]=$op;
  ai=x[i]; xi=x[i+16]; x[i]=$op;
  ai=x[i]; xi=x[i+ 8]; x[i]=$op;
  ai=x[i]; xi=x[i+ 4]; x[i]=$op;
  ai=x[i]; xi=x[i+ 2]; x[i]=$op;
  ai=x[i]; xi=x[i+ 1]; x[i]=$op;
}

__global__ void _$(F)_20_1(int n, $T *x, $T *y) {
  __shared__ $T buffer[$THR];			   //all THR threads in the block write to buffer on their own tid
  int i_start = threadIdx.x+blockIdx.x*blockDim.x; //start at the thread index
  int i_end = n; //end at dim
  int i_step = blockDim.x*gridDim.x; // step is the total number of threads in the system
  int tid = threadIdx.x;
  $T ai, xi;

  // sum the elements assigned to this thread
  ai = $v0;
  for(int i=i_start; i<i_end; i+=i_step) {
     xi=x[i]; xi=$f1; ai=$op;
  }
  buffer[tid] = ai;
  __syncthreads();

  // help sum the entries in the block
  for(int stride=$THR/2; stride>32; stride>>=1) {
    if(tid < stride) {
      ai=buffer[tid]; xi=buffer[stride+tid]; buffer[tid]=$op;
    }
    __syncthreads();   // Q: can this be outside the for loop?
  }

  if(tid<32) {
    _$(F)_20_0(buffer,tid);  // Inlining this does not work.
  }
  __syncthreads();

  if(tid==0) {  // the first thread in the block writes the block result to y
    y[blockIdx.x]=buffer[0];
  }
}

__global__ void _$(F)_20_2($T *y,$T *z) {   // sum block results in y
  __shared__ $T buffer[$BLK];
  $T ai, xi;
  int tid = threadIdx.x;
  buffer[tid] = y[tid];
  __syncthreads();
  for(int stride=$BLK/2; stride>32; stride>>=1) {
    if(tid < stride) {
      ai=buffer[tid]; xi=buffer[stride+tid]; buffer[tid]=$op;
    }
    __syncthreads();
  }
  if(tid<32) {
    _$(F)_20_0(buffer,tid);
  }
  __syncthreads();
  if(tid==0) {
    z[0]=buffer[0];
  }
}

extern "C" {
$DLLEXPORT $T $(F)_20(int n, $T *x) {
  $T r;
  static $T *y;
  static $T *z;
  if (y == NULL) cudaMalloc(&y, $BLK*sizeof($T)); // sum for each block
  if (z == NULL) cudaMalloc(&z, sizeof($T));      // final sum
  _$(F)_20_1<<<$BLK,$THR>>>(n,x,y);
  _$(F)_20_2<<<1,$BLK>>>(y,z);
  cudaMemcpy(&r,z,sizeof($T),cudaMemcpyDeviceToHost);
  return r;
}
$DLLEXPORT $T $(F)_20_stream(int n, $T *x, cudaStream_t STR) {
  $T r, *y, *z;
  cudaMalloc(&y, $BLK*sizeof($T)); // sum for each block
  cudaMalloc(&z, sizeof($T));      // final sum
  _$(F)_20_1<<<$BLK,$THR,0,STR>>>(n,x,y);
  _$(F)_20_2<<<1,$BLK,0,STR>>>(y,z);
  cudaFree(y);
  cudaMemcpy(&r,z,sizeof($T),cudaMemcpyDeviceToHost);
  cudaFree(z);
  return r;
}
}

""")
# TODO: test reduction, has static variables and cudaMalloc
        end
    end
end

for a in reduction_ops
    if !isa(a,Tuple); a=(a,); end
    print(fp,cuda20src(a...))
end

close(fp)


text:
include("formatter.jl")

# filename
datapath = "../depth/system08"
filename = "depth_2430-01.dat"
nx = 720
ny = 540

# load
arraydata = formatter(joinpath(datapath, filename), nx, ny)

# Figure
dx = 2430.0
dy = dx
x = collect(Float64, -1.2000e6+0.5dx:dx:0.5496e6-0.5dx)
y = collect(Float64, -1.2060e6+0.5dy:dy:0.1062e6-0.5dy)

using Plots
gr()
plt = plot(x, y, -arraydata, linetype=:heatmap, c=:delta, clims=(-5000, 5000))
plt = plot!(plt, x, y, -arraydata, linetype=:contour, levels=[0], lc=:black)

# Print
using Printf
open( "matrix_depth_2430-01.csv", "w" ) do fileIO
    [(if j != nx
          @printf(fileIO, "%14.6e,", -arraydata[i,j])
      else
          @printf(fileIO, "%14.6e\n", -arraydata[i,j])
      end) for j=1:nx, i=1:ny]
end


text:
const LEFT_SCALING_COEFFICIENTS = Dict{Int, Vector{Vector{Float64}}}(
2 => Any[
[ 0.6033325119E+00 ; 0.6908955318E+00 ; -0.3983129977E+00 ]
,
[ 0.3751746045E-01 ; 0.4573276599E+00 ; 0.8500881025E+00 ; 0.2238203570E+00 ; -0.1292227434E+00 ]
]
,
3 => Any[
[ 0.3888997639E+00 ; -0.8820782813E-01 ; -0.8478413085E+00 ; 0.3494874367E+00 ]
,
[ -0.6211483178E+00 ; 0.5225273932E+00 ; -0.2000080031E+00 ; 0.3378673486E+00 ; -0.3997707705E+00 ; 0.1648201297E+00 ]
,
[ -0.9587863831E-02 ; 0.3712255319E-03 ; 0.3260097101E+00 ; 0.8016481645E+00 ; 0.4720552620E+00 ; -0.1400420809E+00 ; -0.8542510010E-01 ; 0.3521962365E-01 ]
]
,
4 => Any[
[ 0.9097539258E+00 ; 0.4041658894E+00 ; 0.8904031866E-01 ; -0.1198419201E-01 ; -0.3042908414E-01 ]
,
[ -0.2728514077E+00 ; 0.5090815232E+00 ; 0.6236424434E+00 ; 0.4628400863E+00 ; 0.2467476417E+00 ; -0.1766953329E-01 ; -0.4517364549E-01 ]
,
[ 0.1261179286E+00 ; -0.2308557268E+00 ; -0.5279923525E-01 ; 0.2192651713E+00 ; 0.4634807211E+00 ; 0.7001197140E+00 ; 0.4120325790E+00 ; -0.2622276250E-01 ; -0.6704069413E-01 ]
,
[ -0.2907980427E-01 ; 0.5992807229E-01 ; 0.6176427778E-02 ; -0.4021099904E-01 ; -0.3952587013E-01 ; -0.5259906257E-01 ; 0.3289494480E+00 ; 0.7966378967E+00 ; 0.4901130336E+00 ; -0.2943287768E-01 ; -0.7524762313E-01 ]
]
,
5 => Any[
[ 0.9302490657E+00 ; 0.3488878121E+00 ; 0.1098578445E+00 ; 0.2701025958E-01 ; 0.7897329608E-02 ; 0.7300852033E-02 ]
,
[ -0.3099501188E+00 ; 0.5987214008E+00 ; 0.6208411495E+00 ; 0.3720164550E+00 ; 0.1451060379E+00 ; 0.6263262144E-02 ; 0.1687072021E-01 ; 0.1562115518E-01 ]
,
[ 0.1138401479E+00 ; -0.3641831811E+00; 0.1228916167E-01 ; 0.4117590210E+00 ; 0.5954973448E+00 ; 0.5457944280E+00 ; 0.1756416185E+00 ; -0.1751671276E-01 ; 0.2376581050E-01 ; 0.2200554624E-01 ]
,
[ -0.4098816981E-01 ; 0.1431055982E+00 ; -0.6777711666E-01 ; -0.1740980466E+00 ; -0.9559132536E-01 ; 0.1512981220E+00 ; 0.6357421629E+00 ; 0.6823643465E+00 ; 0.1963091141E+00 ; -0.3301996982E-01 ; 0.2833562039E-01 ; 0.2623688365E-01 ]
,
[ 0.7965029532E-02 ; -0.2796122002E-01 ; 0.1706238600E-01 ; 0.2928655475E-01 ; 0.2857806991E-02 ; -0.4686793277E-01 ; -0.1702677471E+00 ; 0.3028147873E-01 ; 0.6351733467E+00 ; 0.7207789094E+00 ; 0.1995469939E+00 ; -0.3864256419E-01 ; 0.2947288315E-01 ; 0.2728991267E-01 ]
]
,
6 => Any[
[ 0.9231184460E+00 ; 0.3781064509E+00 ; 0.6815972396E-01 ; -0.1063392935E-01 ; -0.9724819798E-02 ; 0.1297887318E-02 ; 0.5723757426E-02 ]
,
[ -0.2868924125E+00 ; 0.5940469387E+00 ; 0.6609604336E+00 ; 0.3412988002E+00 ; 0.9716877076E-01 ; -0.1860855577E-01 ; -0.4013700006E-01 ; 0.1537307481E-02 ; 0.6783960390E-02 ]
,
[ 0.1472870932E+00 ; -0.3468945123E+00 ; 0.6221043773E-01 ; 0.4938022108E+00 ; 0.5849105895E+00 ; 0.4598788833E+00 ; 0.2274224529E+00 ; -0.2788953680E-01 ; -0.6367943024E-01 ; 0.2177711568E-02 ; 0.9609989671E-02 ]
,
[ -0.8324138021E-01 ; 0.2035630921E+00 ; -0.8289131955E-01 ; -0.1939904105E+00 ; -0.1908457968E-01 ; 0.2636403540E+00 ; 0.5123094150E+00 ; 0.6538041187E+00 ; 0.3695601186E+00 ; -0.3993953251E-01 ; -0.9479455728E-01 ; 0.2986558645E-02 ; 0.1317933842E-01 ]
,
[ 0.3164853364E-01 ; -0.8214471961E-01 ; 0.4327551059E-01 ; 0.6830653932E-01 ; -0.4840048148E-02 ; -0.7320834090E-01 ; -0.5786918156E-01 ; 0.2055855208E-01 ; 0.4001944206E+00 ; 0.7644983569E+00 ; 0.4653802512E+00 ; -0.4686421163E-01 ; -0.1137136979E+00 ; 0.3413297317E-02 ; 0.1506248690E-01 ]
,
[ -0.5550804971E-02 ; 0.1471087926E-01 ; -0.8859117912E-02 ; -0.1158923365E-01 ; 0.1569832259E-02 ; 0.1157111171E-01 ; 0.7445526684E-02 ; 0.2902493903E-01 ; -0.2999940975E-01 ; -0.6576340468E-01 ; 0.3438258786E+00 ; 0.7867130346E+00 ; 0.4895844920E+00 ; -0.4825468670E-01 ; -0.1177993251E+00 ; 0.3488475665E-02 ; 0.1539424027E-01 ]
]
,
7 => Any[
[ 0.9426568713E+00 ; 0.2691475418E+00 ; 0.1685897688E+00 ; 0.9379442214E-01 ; 0.4001600171E-01 ; 0.1057520816E-01 ; -0.1804517915E-02 ; 0.4620417362E-02 ]
,
[ -0.3237338194E+00 ; 0.6746802222E+00 ; 0.5985769136E+00 ; 0.2331427899E+00 ; 0.7615188825E-02 ; 0.8787238208E-01 ; 0.1327822780E+00 ; -0.4208296665E-01 ; -0.4763766998E-02 ; 0.1219755973E-01 ]
,
[ -0.2713311808E-01 ; -0.2899110477E+00 ; 0.6661404639E-01 ; 0.7251175151E+00 ; 0.5750729858E+00 ; 0.4362186445E-01 ; -0.1857980605E+00 ; 0.1201045634E+00 ; 0.5011061230E-01 ; -0.2991531277E-01 ; -0.1573393605E-02 ; 0.4028652635E-02 ]
,
[ 0.2428297386E-01 ; -0.1012534619E-01 ; -0.1589124403E+00 ; -0.1400872185E+00 ; 0.3332116140E+00 ; 0.7053065273E+00 ; 0.5793528972E+00 ; 0.3896614469E-02 ; -0.5955471765E-01 ; 0.7479188863E-01 ; 0.3081374376E-01 ; -0.1340206604E-01 ; -0.1047350551E-02 ; 0.2681726647E-02 ]
,
[ 0.2396415492E-02 ; -0.2199441967E-01 ; 0.3831273498E-01 ; 0.8416826933E-02 ; -0.1404553727E+00 ; -0.9975512873E-01 ; 0.2671255526E+00 ; 0.7725679637E+00 ; 0.5400947777E+00 ; 0.1395136806E-01 ; -0.4947167749E-01 ; 0.6809969285E-01 ; 0.3044230228E-01 ; -0.1259630803E-01 ; -0.1045026849E-02 ; 0.2675776840E-02 ]
,
[ -0.9493922980E-03 ; 0.8445740060E-02 ; -0.8462283108E-02 ; -0.3100522289E-02 ; 0.2269052507E-01 ; -0.9675176425E-02 ; -0.1013545517E+00 ; -0.1405275956E+00 ; 0.2877816730E+00 ; 0.7686169120E+00 ; 0.5358841401E+00 ; 0.1743190445E-01 ; -0.4949055461E-01 ; 0.6785067390E-01 ; 0.3050565786E-01 ; -0.1262873733E-01 ; -0.1047102354E-02 ; 0.2681091142E-02 ]
,
[ 0.1364120169E-03 ; -0.1153014522E-02 ; 0.1050196147E-02 ; 0.6396328807E-03 ; -0.1940525665E-02 ; 0.1962825019E-02 ; 0.9431646581E-02 ; 0.4027633417E-02 ; -0.1076854888E+00 ; -0.1401281648E+00 ; 0.2886799721E+00 ; 0.7677614604E+00 ; 0.5360881498E+00 ; 0.1744975917E-01 ; -0.4954996630E-01 ; 0.6789074612E-01 ; 0.3051526119E-01 ; -0.1263602514E-01 ; -0.1047379021E-02 ; 0.2681799545E-02 ]
]
,
8 => Any[
[ 0.9281136260E+00 ; 0.3668618286E+00 ; 0.6266997447E-01 ; -0.7647264163E-02 ; -0.5088004810E-02 ; 0.1171898539E-02 ; 0.1656055473E-02 ; -0.1929333000E-03 ; -0.1203653707E-02 ]
,
[ -0.2926634432E+00 ; 0.6373078980E+00 ; 0.6452435440E+00 ; 0.2965161471E+00 ; 0.5906254343E-01 ; -0.1366965641E-01 ; -0.1323318522E-01 ; 0.2213708145E-02 ; 0.8306912600E-02 ; -0.1892199826E-03 ; -0.1180561737E-02 ]
,
[ 0.1537394280E+00 ; -0.3933877381E+00 ; 0.1368645026E+00 ; 0.6064470308E+00 ; 0.5685338138E+00 ; 0.3166230149E+00 ; 0.9637901837E-01 ; -0.2215743488E-01 ; -0.4105959919E-01 ; 0.3062891878E-02 ; 0.1191510029E-01 ; -0.2473506634E-03 ; -0.1543244666E-02 ]
,
[ -0.9143117079E-01 ; 0.2571933236E+00 ; -0.1858137201E+00 ; -0.2318000501E+00 ; 0.1598859051E+00 ; 0.4871009258E+00 ; 0.5734443542E+00 ; 0.4450618899E+00 ; 0.2033090498E+00 ; -0.3331081673E-01 ; -0.6859620275E-01 ; 0.4406096842E-02 ; 0.1763488599E-01 ; -0.3388224811E-03 ; -0.2113946167E-02 ]
,
[ 0.5709470789E-01 ; -0.1665850443E+00 ; 0.1454047216E+00 ; 0.1015538648E+00 ; -0.1362852159E+00 ; -0.1769345243E+00 ; 0.8596479652E-02 ; 0.3062987789E+00 ; 0.5431752460E+00 ; 0.6140955155E+00 ; 0.3284966144E+00 ; -0.4723534035E-01 ; -0.1039762360E+00 ; 0.6053819361E-02 ; 0.2473853830E-01 ; -0.4480360998E-03 ; -0.2795340476E-02 ]
,
[ -0.2771885178E-01 ; 0.8389262409E-01 ; -0.8147463473E-01 ; -0.3866640174E-01 ; 0.7464550842E-01 ; 0.6920099668E-01 ; -0.2231653624E-01 ; -0.1020129060E+00 ; -0.6275852804E-01 ; 0.8683887629E-01 ; 0.4540741128E+00 ; 0.7328223558E+00 ; 0.4319437621E+00 ; -0.5734179466E-01 ; -0.1314896433E+00 ; 0.7195965493E-02 ; 0.2979946085E-01 ; -0.5190323961E-03 ; -0.3238293222E-02 ]
,
[ 0.8529185218E-02 ; -0.2624362023E-01 ; 0.2697489980E-01 ; 0.9748173003E-02 ; -0.2431726904E-01 ; -0.1901319060E-01 ; 0.8695522469E-02 ; 0.2729552258E-01 ; 0.1231155208E-01 ; 0.9187597846E-02 ; -0.4745631970E-01 ; -0.2924026466E-01 ; 0.3831732042E+00 ; 0.7723764353E+00 ; 0.4743837775E+00 ; -0.6082976218E-01 ; -0.1418145038E+00 ; 0.7565491348E-02 ; 0.3149214931E-01 ; -0.5401012058E-03 ; -0.3369743560E-02 ]
,
[ -0.1148179452E-02 ; 0.3567347972E-02 ; -0.3784785333E-02 ; -0.1105680377E-02 ; 0.3387180654E-02 ; 0.2395725348E-02 ; -0.1281174092E-02 ; -0.3407989030E-02 ; -0.1283416571E-02 ; -0.9841020551E-02 ; 0.6341196709E-02 ; 0.4619539219E-01 ; -0.2943416082E-01 ; -0.5094613096E-01 ; 0.3655480429E+00 ; 0.7770499808E+00 ; 0.4810695095E+00 ; -0.6126039684E-01 ; -0.1432436897E+00 ; 0.7606483137E-02 ; 0.3168981524E-01 ; -0.5420982042E-03 ; -0.3382203026E-02 ]
]
)


text:
# module Bukdu

abstract ApplicationRouter

"""
    Router

Use to route for the incoming path into the controller and action.

Verbs are `get`, `post`, `delete`, `patch`, `put`.

`scope` and `resources` are used to namespace something.

```julia
Router() do
    get("/", WelcomeController, index)
end
```
"""
immutable Router <: ApplicationRouter
end

immutable NoRouteError
    message
end

include("router/route.jl")
include("router/scope.jl")
include("router/resource.jl")
include("router/conn.jl")

import Base: reset
import URIParser: escape

function reset{AR<:ApplicationRouter}(::Type{AR})
    delete!(Routing.routing_map, AR)
end

function (::Type{AR}){AR<:ApplicationRouter}(context::Function)
    empty!(RouterRoute.routes)
    context()
    Routing.routing_map[AR] = copy(RouterRoute.routes)
    empty!(RouterScope.stack)
    nothing
end

function (::Type{AR}){AR<:ApplicationRouter}(verb::Function, path::String, args...; kw...)
    routes = haskey(Routing.routing_map, AR) ? Routing.routing_map[AR] : Vector{Route}()
    data = Vector{UInt8}()
    if !isempty(args) || !isempty(kw)
        data = Vector{UInt8}(join(map(vcat(args..., kw...)) do kv
            (k,v) = kv
            string(k, '=', escape(v))
        end, '&'))
    end
    Routing.request(routes, verb, path, data) do route
        Base.function_name(route.verb) == Base.function_name(verb)
    end
end

"""
    scope

Scoping around the routes.

```julia
scope("/admin") do
    get("/users/:id", UserController, index)
end
```
"""
function scope(context::Function, path::String; kw...)
    Routing.do_scope(context, merge(Dict(:path=>path), Dict(kw)))
end

function scope(context::Function, path::String, modul::Module; kw...)
    Routing.do_scope(context, merge(Dict(:path=>path), Dict(kw)))
end

function scope(context::Function; kw...)
    Routing.do_scope(context, Dict(kw))
end

"""
    resources

Generating RESTful routes.

```julia
resources("/users", UserController, only= [index])
```
"""
function resources{AC<:ApplicationController}(path::String, ::Type{AC}; kw...)
    Routing.add_resources(()->nothing, path, AC, Dict(kw))
end

function resources{AC<:ApplicationController}(context::Function, path::String, ::Type{AC}; kw...)
    Routing.add_resources(context, path, AC, Dict(kw))
end

module Routing

import ..Bukdu: ApplicationController
import ..Bukdu: RouterRoute, Route, RouterScope, RouterResource, Resource, NoRouteError
import ..Bukdu: Logger
import ..Bukdu: Conn
import ..Bukdu: index, edit, new, show, create, update, delete
import ..Bukdu: get, post, delete, patch, put
import ..Bukdu: plugins, before, after
import ..Bukdu: Assoc
import URIParser: URI, unescape_form
import HttpCommon: parsequerystring

const SLASH = '/'
const COLON = ':'

immutable Branch
    query_params::Assoc
    params::Assoc
    action::Function
    host::String
    assigns::Dict{Symbol,Any}
end

task_storage = Dict{Task,Branch}()
routing_map = Dict{Type,Vector{Route}}()

# route
function match{AC<:ApplicationController}(verb::Function, path::String, ::Type{AC}, action::Function, options::Dict)
    add_route(:match, verb, path, AC, action, options)
end

function add_route{AC<:ApplicationController}(kind::Symbol, verb::Function, path::String, ::Type{AC}, action::Function, options::Dict)
    route = RouterScope.route(kind, verb, path, AC, action, options)
    push!(RouterRoute.routes, route)
    route
end

# scope
function do_scope(context::Function, options::Dict)
    RouterScope.push_scope!(options)
    context()
    RouterScope.pop_scope!()
end

# resources
function add_resources{AC<:ApplicationController}(context::Function, path::String, ::Type{AC}, options::Dict)
    resource = RouterResource.build(path, AC, options)
    Routing.do_scope(context, resource.member)
    add_route(resource)
end

function add_route(resource::Resource)
    path = resource.path
    options = resource.route
    if resource.singleton
        for (action,verb,routepath) in [(index,  get,    ""),
                                        (show,   get,    ""),
                                        (new,    get,    "/new"),
                                        (edit,   get,    "/edit"),
                                        (create, post,   ""),
                                        (delete, delete, ""),
                                        (update, patch,  ""),
                                        (update, put,    "")]
            if action in RouterResource.controller_actions
                match(verb, string(path,routepath), resource.controller, action, options)
            end
        end
    else
        param = resource.param
        for (action,verb,routepath) in [(index,  get,    ""),
                                        (show,   get,    "/:$param"),
                                        (new,    get,    "/new"),
                                        (edit,   get,    "/:$param/edit"),
                                        (create, post,   ""),
                                        (delete, delete, "/:$param"),
                                        (update, patch,  "/:$param"),
                                        (update, put,    "/:$param")]
            if action in RouterResource.controller_actions
                match(verb, string(path,routepath), resource.controller, action, options)
            end
        end
    end
end

function trail(s::String, n)
    length(s) > n > 2 ? string(s[1:n-2], "..") : s
end

function debug_route{AC<:ApplicationController}(route, path, ::Type{AC})
    verb = uppercase(string(Base.function_name(route.verb)))
    path_pad = 25
    trailed_path = trail(path, path_pad)
    rpaded_path = rpad(Logger.with_color(:bold, trailed_path), path_pad)
    verb, rpaded_path, "$(Base.function_name(route.action))(::$AC)"
end

function error_route(route, path, controller, ex, callstack)
    tuple(
        debug_route(route, path, controller)...,
        '\n',
        Logger.with_color(:red, ex),
        callstack)
end

function request(compare::Function, routes::Vector{Route}, verb::Function, path::String, data::Vector{UInt8})::Conn
    uri = URI(path)
    reqsegs = split(uri.path, SLASH)
    length_reqsegs = length(reqsegs)
    for route in routes
        rousegs = split(route.path, SLASH)
        if compare(route) && length_reqsegs==length(rousegs)
            if !isempty(route.host)
                if endswith(route.host, ".")
                    !startswith(uri.host, route.host) && continue
                else
                    !endswith(uri.host, route.host) && continue
                end
            end
            matched = all(enumerate(rousegs)) do idx_rouseg
                (idx,rouseg) = idx_rouseg
                startswith(rouseg, COLON) ? true : reqsegs[idx]==rouseg
            end
            if matched
                function startswithcolon(idx_rouseg)
                    (idx,rouseg) = idx_rouseg
                    startswith(rouseg, COLON)
                end
                params = Assoc(map(filter(startswithcolon, enumerate(rousegs))) do idx_rouseg
                    (idx,rouseg) = idx_rouseg
                    (replace(rouseg, r"^:", ""),String(reqsegs[idx]))
                end)
                C = route.controller
                controller = C()
                query_params = Assoc(parsequerystring(uri.query))
                if verb == post && !isempty(data)
                    merge!(query_params, Assoc(parsequerystring(unescape_form(String(data)))))
                end
                branch = Branch(query_params, params, route.action, uri.host, route.assigns)
                task = current_task()
                task_storage[task] = branch
                if method_exists(plugins, (C,))
                    plugins(controller)
                end
                if method_exists(before, (C,))
                    before(controller)
                end
                result = nothing
                try
                    Logger.debug() do
                        debug_route(route, path, C)
                    end
                    result = route.action(controller)
                catch ex
                    Logger.error() do
                        error_route(route, path, C, ex, stacktrace(catch_backtrace()))
                    end
                    result = Conn(400, Dict{String,String}(), "bad request $ex", params, query_params, route.private, route.assigns)
                end
                if method_exists(after, (C,))
                    after(controller)
                end
                pop!(task_storage, task)
                if isa(result, Conn)
                    return Conn(result.status, result.resp_header, result.resp_body, params, query_params, route.private, route.assigns)
                else
                    return Conn(200, Dict{String,String}(), result, params, query_params, route.private, route.assigns)
                end
            end
        end
    end
    Logger.warn() do
        uppercase(string(Base.function_name(verb))), Logger.with_color(:bold, path)
    end
    throw(NoRouteError(""))
end

end # module Bukdu.Routing


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

mutable struct ApplicationGatewayRewriteRuleSetPropertiesFormat <: SwaggerModel
    rewriteRules::Any # spec type: Union{ Nothing, Vector{ApplicationGatewayRewriteRule} } # spec name: rewriteRules
    provisioningState::Any # spec type: Union{ Nothing, ProvisioningState } # spec name: provisioningState

    function ApplicationGatewayRewriteRuleSetPropertiesFormat(;rewriteRules=nothing, provisioningState=nothing)
        o = new()
        validate_property(ApplicationGatewayRewriteRuleSetPropertiesFormat, Symbol("rewriteRules"), rewriteRules)
        setfield!(o, Symbol("rewriteRules"), rewriteRules)
        validate_property(ApplicationGatewayRewriteRuleSetPropertiesFormat, Symbol("provisioningState"), provisioningState)
        setfield!(o, Symbol("provisioningState"), provisioningState)
        o
    end
end # type ApplicationGatewayRewriteRuleSetPropertiesFormat

const _property_map_ApplicationGatewayRewriteRuleSetPropertiesFormat = Dict{Symbol,Symbol}(Symbol("rewriteRules")=>Symbol("rewriteRules"), Symbol("provisioningState")=>Symbol("provisioningState"))
const _property_types_ApplicationGatewayRewriteRuleSetPropertiesFormat = Dict{Symbol,String}(Symbol("rewriteRules")=>"Vector{ApplicationGatewayRewriteRule}", Symbol("provisioningState")=>"ProvisioningState")
Base.propertynames(::Type{ ApplicationGatewayRewriteRuleSetPropertiesFormat }) = collect(keys(_property_map_ApplicationGatewayRewriteRuleSetPropertiesFormat))
Swagger.property_type(::Type{ ApplicationGatewayRewriteRuleSetPropertiesFormat }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_ApplicationGatewayRewriteRuleSetPropertiesFormat[name]))}
Swagger.field_name(::Type{ ApplicationGatewayRewriteRuleSetPropertiesFormat }, property_name::Symbol) =  _property_map_ApplicationGatewayRewriteRuleSetPropertiesFormat[property_name]

function check_required(o::ApplicationGatewayRewriteRuleSetPropertiesFormat)
    true
end

function validate_property(::Type{ ApplicationGatewayRewriteRuleSetPropertiesFormat }, name::Symbol, val)
end


text:
using UnixMmap
using UnixMmap: mmap, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_SHARED
using Test

@testset "Mapping files by name" begin
    data = [zeros(Float64, 100); ones(Float64, 256)]
    byteoff = 100 * sizeof(Float64)

    mktemp() do path, io
        write(io, zeros(Float64, 100))
        write(io, ones(Float64, 256))
        close(io)

        # Open and read
        A = mmap(path, Array{Float64}, 356)
        @test A == data

        # Open and read with offset
        A = mmap(path, Array{Float64}, 256; offset = byteoff)
        @test all(isone, A)

        # File exists → opened by default as read-only
        @test_throws ReadOnlyMemoryError A[1] = 0.0

        # Re-open with read-write permissions
        A = mmap(path, Array{Float64}, 256; offset = byteoff, prot = PROT_READ | PROT_WRITE)
        @test all(isone, A)
        A[1] = 2.0
        @test A[1] == 2.0
        A[1] = 1.0

        # Unspecified length defaults to openening remainder of file
        A = mmap(path, Array{Float64}; offset = byteoff)
        @test length(A) == 256
        @test all(isone, A)
        # again without an offset
        A = mmap(path, Array{Float64})
        @test length(A) == length(data)
        @test A == data

        # Unspecified array type defaults to UInt8
        A = mmap(path)
        @test A == reinterpret(UInt8, data)

        A = nothing; GC.gc()
    end
end

@testset "Mapping files by IO handle" begin
    data = [zeros(Float64, 100); ones(Float64, 256)]
    byteoff = 100 * sizeof(Float64)

    mktemp() do path, io
        write(io, zeros(Float64, 100))
        write(io, ones(Float64, 256))
        close(io)

        io = open(path, "r")
        # Open and read
        A = mmap(io, Array{Float64}, 356)
        @test A == data

        # Open and read with offset
        A = mmap(io, Array{Float64}, 256; offset = byteoff)
        @test all(isone, A)

        # File exists → opened by default as read-only
        @test_throws ReadOnlyMemoryError A[1] = 0.0

        # File handle opened read-only, but requesting read-write
        @test_throws SystemError mmap(io, Array{Float64}, 256; prot = PROT_READ | PROT_WRITE)

        # Reopen as read-write
        close(io)
        io = open(path, "r+")
        A = mmap(path, Array{Float64}, 256; offset = byteoff, prot = PROT_READ | PROT_WRITE)
        @test all(isone, A)
        A[1] = 2.0
        @test A[1] == 2.0
        A[1] = 1.0

        # Unspecified length defaults to openening remainder of file
        A = mmap(io, Array{Float64}; offset = byteoff)
        @test length(A) == 256
        @test all(isone, A)
        # again without an offset
        A = mmap(io, Array{Float64})
        @test length(A) == length(data)
        @test A == data

        # Unspecified array type defaults to UInt8
        A = mmap(io)
        @test A == reinterpret(UInt8, data)

        close(io)
        A = nothing; GC.gc()
    end
end

@testset "Growing mapped files" begin
    mktemp() do path, io
        close(io)
        @test filesize(path) == 0
        # Note! Require explicit write perms since the file `path` now exists
        A = mmap(path, Array{Float32}, 500; prot = PROT_READ | PROT_WRITE)
        @test filesize(path) == 2000
        @test all(iszero, A)
    end
    mktemp() do path, io
        close(io)
        @test filesize(path) == 0
        A = mmap(path, Array{Float32}, 500; offset = 400, prot = PROT_READ | PROT_WRITE)
        @test filesize(path) == 2400
        @test all(iszero, A)
    end
    mktemp() do path, io
        @test filesize(io) == 0
        # Here, `io` will have already been opened with write perms, so defaults OK
        A = mmap(io, Array{Float32}, 500)
        @test filesize(io) == 2000
        @test all(iszero, A)
    end
    mktemp() do path, io
        @test filesize(io) == 0
        A = mmap(io, Array{Float32}, 500; offset = 400)
        @test filesize(io) == 2400
        @test all(iszero, A)
    end

    # If grow is *false*, the memory map cannot be accessed without throwing a
    # SIGBUS signal, but we can at least check that the file has not changed size.
    mktemp() do path, io
        @test filesize(io) == 0
        A = mmap(io, Array{Float32}, 500; offset = 400, grow = false)
        @test filesize(io) == 0
        A = nothing
    end

    GC.gc()
end

@testset "Shared and private file maps" begin
    data = collect(range(-1.0, stop=1.0, length=10))

    # Default is shared mapping
    mktemp() do path, io
        write(io, data)
        flush(io)
        seek(io, 0)

        A = mmap(io, Array{Float64})
        B = mmap(io, Array{Float64})

        A[1] = 0.0
        @test B[1] == 0.0
    end

    # Check that private mapping request works
    mktemp() do path, io
        write(io, data)
        flush(io)
        seek(io, 0)

        A = mmap(io, Array{Float64}; flags = MAP_PRIVATE)
        B = mmap(io, Array{Float64}; flags = MAP_PRIVATE)

        A[1] = 0.0
        @test B[1] == -1.0
    end
end

@testset "Anonymous memory maps" begin
    A = mmap(Array{Int16}, 500)
    @test size(A) == (500,)

    A = mmap(Array{Int16}, (50, 10))
    @test size(A) == (50, 10)
end

@testset "In-core" begin
    A = mmap(Array{Int}, 5000)
    ic = UnixMmap.mincore(A)
    # Just checking that the function works
    @test ic isa Vector{Bool}

    # On linux and if the array not immediately mapped by default, take the opportunity
    # to test for non-standard flag: MAP_POPULATE will force fully mapping into RAM
    if Sys.islinux() && any(!, ic)
        B = mmap(Array{Int}, 5000; flags = MAP_SHARED | UnixMmap.MAP_POPULATE)
        @test all(UnixMmap.mincore(B))
    end
end

@testset "Giving advice" begin
    # It's hard to test behavior of the advise flags --- just check for not erroring
    A = mmap(Array{Int}, 500)
    @test A == UnixMmap.madvise!(A, UnixMmap.MADV_WILLNEED)
end


text:
# ClusterManager for HTCondor

export HTCManager, addprocs_htc

struct HTCManager <: ClusterManager
    np::Integer
end

function condor_script(portnum::Integer, np::Integer, params::Dict)
    dir = params[:dir]
    exename = params[:exename]
    exeflags = params[:exeflags]
    extrajdl = get(params, :extrajdl, [])
    extraenv = get(params, :extraenv, [])
    extrainputs = get(params, :extrainputs, [])
    telnetexe = get(params, :telnetexe, "/usr/bin/telnet")
    home = ENV["HOME"]
    hostname = ENV["HOSTNAME"]
    jobname = "julia-$(getpid())"
    tdir = "$home/.julia-htc"
    run(`mkdir -p $tdir`)

    scriptf = open("$tdir/$jobname.sh", "w")
    println(scriptf, "#!/bin/sh")
    for line in extraenv
        println(scriptf, line)
    end
    println(scriptf, "cd $(Base.shell_escape(dir))")
    println(scriptf, "$(Base.shell_escape(exename)) $exeflags $(Base.shell_escape(worker_arg())) | $telnetexe $(Base.shell_escape(hostname)) $portnum")
    close(scriptf)

    input_files = ["$tdir/$jobname.sh"]
    push!(input_files, extrainputs...)
    subf = open("$tdir/$jobname.sub", "w")
    println(subf, "executable = /bin/bash")
    println(subf, "arguments = ./$jobname.sh")
    println(subf, "universe = vanilla")
    println(subf, "should_transfer_files = yes")
    println(subf, "transfer_input_files = $(join(input_files, ','))")
    println(subf, "Notification = Error")
    for line in extrajdl
        println(subf, line)
    end
    for i = 1:np
        println(subf, "output = $tdir/$jobname-$i.o")
        println(subf, "error= $tdir/$jobname-$i.e")
        println(subf, "queue")
    end
    close(subf)

    "$tdir/$jobname.sub"
end

function launch(manager::HTCManager, params::Dict, instances_arr::Array, c::Condition)
    try
        portnum = rand(8000:9000)
        _, server = listenany(Sockets.getaddrinfo("0.0.0.0"), portnum)
        np = manager.np

        script = condor_script(portnum, np, params)
        cmd = `condor_submit $script`
        if !success(cmd)
            println("batch queue not available (could not run condor_submit)")
            return
        end
        print("Waiting for $np workers: ")

        for i=1:np
            conn = accept(server)
            config = WorkerConfig()

            config.io = conn

            push!(instances_arr, config)
            notify(c)
            print("$i ")
        end
        println(".")

   catch e
        println("Error launching condor")
        println(e)
   end
end

function manage(manager::HTCManager, id::Integer, config::WorkerConfig, op::Symbol)
    if op == :finalize
        if !isnull(config.io)
            close(get(config.io))
        end
#     elseif op == :interrupt
#         job = config[:job]
#         task = config[:task]
#         # this does not currently work
#         if !success(`qsig -s 2 -t $task $job`)
#             println("Error sending a Ctrl-C to julia worker $id (job: $job, task: $task)")
#         end
    end
end

addprocs_htc(np::Integer) = addprocs(HTCManager(np))


text:
module TestConstraints

# TODO: Rewrite this

import Wordle
import Test: @test, @test_throws

constraints = Wordle.Constraints()

@test all(c -> c === 0, constraints.lower_bound.counts)
@test all(c -> c === false, constraints.global_ban.flags)
@test all(c -> c === false, constraints.is_exact_match)
@test all(c -> isa(c, Char), constraints.match)
for i in 1:5
    @test all(c -> c === false, constraints.local_ban[i].flags)
end

@test size(constraints.lower_bound.counts) === (26, )
@test size(constraints.global_ban.flags) === (26, )
@test size(constraints.is_exact_match) === (5, )
@test size(constraints.match) === (5, )
for i in 1:5
    @test size(constraints.local_ban[i].flags) === (26, )
end

end # module


text:
# ---
# title: 757. Set Intersection Size At Least Two
# id: problem757
# author: Tian Jun
# date: 2020-10-31
# difficulty: Hard
# categories: Greedy
# link: <https://leetcode.com/problems/set-intersection-size-at-least-two/description/>
# hidden: true
# ---
#
# An integer interval `[a, b]` (for integers `a < b`) is a set of all
# consecutive integers from `a` to `b`, including `a` and `b`.
#
# Find the minimum size of a set S such that for every integer interval A in
# `intervals`, the intersection of S with A has a size of at least two.
#
#
#
# **Example 1:**
#
#
#
#     Input: intervals = [[1,3],[1,4],[2,5],[3,5]]
#     Output: 3
#     Explanation: Consider the set S = {2, 3, 4}.  For each interval, there are at least 2 elements from S in the interval.
#     Also, there isn't a smaller size set that fulfills the above condition.
#     Thus, we output the size of this set, which is 3.
#
#
# **Example 2:**
#
#
#
#     Input: intervals = [[1,2],[2,3],[2,4],[4,5]]
#     Output: 5
#     Explanation: An example of a minimum sized set is {1, 2, 3, 4, 5}.
#
#
#
#
# **Constraints:**
#
#   * `1 <= intervals.length <= 3000`
#   * `intervals[i].length == 2`
#   * `0 <= ai < bi <= 108`
#
#
## @lc code=start
using LeetCode

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


text:
using ConstrainedDynamics

# Parameters
ex = [1.;0.;0.]
ey = [0.;1.;0.]
ez = [0.;0.;1.]

l1 = 1.0
x, z = .1, .1
b1 = Box(x, l1, z, l1 * 100, color = RGBA(1., 1., 0.))
b2 = Box(x, l1, z, l1 * 1, color = RGBA(1., 0., 0.))

vert11 = [0.;l1 / 2;0.]
vert12 = -vert11

# Links
origin = Origin{Float64}()
link1 = Body(b1)
link2 = Body(b2)

# Constraints
joint0to1 = EqualityConstraint(OriginConnection(origin, link1))
# joint0to1 = EqualityConstraint(Fixed(origin,link1,zeros(3),zeros(3)))
joint1to2 = EqualityConstraint(Revolute(link1, link2, vert12, vert11, ex))

links = [link1; link2]
constraints = [joint0to1;joint1to2]
shapes = [b1;b2]

mech = Mechanism(origin, links, constraints, shapes = shapes, g = 0.)
setPosition!(mech,link1,link2,p1 = vert12,p2 = vert11)

setForce!(mech, joint1to2, [nothing;[0.05]])

simulate!(mech,save = true)
visualize!(mech)


text:
using Dispersal, Dates

#### Parasitoid growth rule object and method #####################
struct Parasitism{R,W,GR,M,HS,A,B} <: CellRule{R,W}
    rate::GR
    mortality::M
    halfsat::HS
    a::A
    b::B
end

function Dispersal.applyrule(data, rule::Parasitism, (H, P), I)
    γ = rule.mortality; halfsat = rule.halfsat; a = rule.a; b = rule.b
    rP = get(data, rule.rate, I) * 7 # Growthrate for the cell/timestep
    h = 1 / (a * exp(b * rP)) # Handling time
    β = 1 / (h * halfsat) # Encounter rate
    R = β * H / (1 + h * β * H) # Holling type II response
    δ = h * (rP - γ) # Conversion efficiency
    dHdt = -R * P # Change in host population
    dPdt = δ * R * P * rP - γ * P # Change in parasitoid population
    return (H + dHdt, P + dPdt) # Updated populations for the cell
end

function define_rules()

    ### Growth rule #######################################
    carrycap = 1f9
    growth = LogisticGrowth{:H}(
        rate=Aux(:rH), carrycap=carrycap, timestep=Day(1),
        nsteps_type=Float32, # for type stability and performance with a Float32 grid
    )

    ### Allee extinction rule #############################
    allee = AlleeExtinction{:H}(; minfounders=20.0f0)

    #### Host local dispersal rule ########################
    localdisp = InwardsDispersal{:H}(;
        radius=1, formulation=ExponentialKernel(0.25f0), cellsize=1.0f0,
    )

    ### Wind dispersal rule ###############################
    wind = SetCell{:H}() do data, H, I
        H > zero(H) || return nothing # Ignore empty cells
        rand(Float32) < 0.01f0 || return nothing # Randomise a dispersal event
        # Randomise a destination
        # Need to do this a little more manually than in the paper
        # for GPU compat
        # dest = I .+ (rand(-20:20), rand(-20:20))
        dest = I .+ (unsafe_trunc(Int, rand(Float32) * 40 - 20),
                     unsafe_trunc(Int, rand(Float32) * 40 - 20))
        if isinbounds(data, dest)
            # Update dest cell and current cell, if dest is on the grid
            add!(data[:H], H / 10, dest...)
            sub!(data[:H], H / 10, I...)
        end
        return nothing
    end

    # Construct a Parasitism rule
    parasitism = Parasitism{Tuple{:H,:P}}(Aux(:rP), 0.2f0, 1f8, 2.0f0, 5.0f0)

    #### Parasitoid local dispersal rules ##################
    localdisp_p = InwardsDispersal{:P}(;
        radius=1, formulation=ExponentialKernel(; λ=0.18f0), cellsize=1.0f0
    )
    allee_p = AlleeExtinction{:P}(; minfounders=20.0f0)

    return (; growth, allee, localdisp, wind, parasitism, localdisp_p, allee_p, carrycap)
end


text:
using ConjugatePriors
using Rmath
using StatsBase

function microvctest(arg...; covFile::String = "", responseFile::String = "",
                     kernelFile::String = "",  kadjFile::String = "",
                     outFile::String = "", zFile::String = "", yIdx::Int64 = 3,
                     IDidx::Int64 = 1,  xIdx::Array{Int64, 1} = vcat(3,4,5),
                     out::Bool = false,
                     longitudinal::Bool = true, fine::Bool = false,
                     test::String = "eRLRT", device::String = "CPU",
                     infLambda::Float64 = 0.0, nMMmax::Int64 = 0,
                     nBlockAscent::Int64 = 1000, nNullSimPts::Int64 = 1000000,
                     nNullSimNewtonIter::Int64 = 15, tolX::Float64 = 1e-4,
                     MemoryLimit::Int64 = 200000000, lowRank::Float64 = 0.4,
                     pvalueComputing::String = "chi2")

##VCmicrobiome::--------------set default maximum MM iteration-----------------#
if nMMmax == 0  && test == "eLRT"
  nMMmax = 10
elseif nMMmax == 0 && test == "eRLRT"
  nMMmax = 1000
end

##VCmicrobiome::-----------------------get kernel------------------------------#
if isempty(kernelFile)
  error("mVctest:kernelwrongn\n", "# no kernel matrix")
else
  K = readdlm(kernelFile,',')
  if typeof(K[1,1]) != Float64
    K = K[2:end,:]
    K = convert(Array{Float64, 2}, K)
  else
    K = convert(Array{Float64, 2}, K)
  end
end

nObs = length(K[:, 1])

##VCmicrobiome::-----------------------get kernel adj -------------------------#
if fine & isempty(kadjFile)
  error("mVctest:kernelwrongn\n", "# no kernel adjustment matrix")
elseif fine & !isempty(kadjFile)
  Kadj = readdlm(kadjFile,',')
  if typeof(Kadj[1,1]) != Float64
    Kadj = Kadj[2:end,:]
    Kadj = convert(Array{Float64, 2}, Kadj)
  else
    Kadj = convert(Array{Float64, 2}, Kadj)
  end
end

#VCmicrobiome::------------------ get covariate and response-------------------#
if isempty(covFile)
  X = ones(nObs, 1) # N-by-1 matrix with all elements equal to 1
  X = convert(Array{Float64, 2}, X)
else
  covariate = readdlm(covFile,',')
  X = covariate[2:end, xIdx]
  if size(X, 1) != nObs
    error("VCmicrobiome:covwrongn\n",
    "# N in covariate file does not match dimension of kernel matrix")
  end
  X = convert(Array{Float64, 2}, X)
end

if isempty(responseFile)
  error("VCmicrobiome:noresponse\n", "# need to provide response file")
else
  Y = readdlm(responseFile,',')
  yname = Y[1, yIdx]
  Y = Y[2:end, yIdx]
  if size(Y, 1) != nObs
    error("VCmicrobiome:ywrongn\n",
    "# N in response file does not match dimension of Kernel")
  end
  y = convert(Array{Float64, 1}, Y[:])
end

if longitudinal && isempty(zFile)
  if isempty(IDidx) || isempty(covFile)
    error("VCmicrobiome:noid\n",
    "# need subject ID if Z matrix not provided")
  else
    id = covariate[2:end, IDidx]
  end
  dic = StatsBase.countmap(id)
  IDunq = unique(dic)
  Z = cat([1, 2],ones(dic[id[1]], 1))
  for i = 2:length(IDunq)
    Z = cat([1, 2], Z, ones(dic[id[i]], 1))
  end
  ZZ = Z * Z'
end

if isempty(zFile) == false
    Z = readdlm(zFile,',')
    Z = Z[2:end, :]
    Z = convert(Array{Float64, 2}, Z)
    ZZ = Z * Z'
end

offset = 0

# prepare output
if isempty(outFile)
  outFile = string(responseFile, "-", test,"-julia.out");
end

outresults = Array{Float64}(1, 3)
Xsvd = svdfact(X, thin = false);
rankX = countnz(Xsvd[:S] .> nObs * eps(Xsvd[:S][1]));
XtNullBasis = Xsvd[:U][:, rankX + 1 : end];

if longitudinal == false && fine == false
  ynew = zeros(nObs - rankX);
  BLAS.gemv!('N', 1.0, XtNullBasis', y, 0.0, ynew);
  yShift = Float64[];
  PrePartialSumW = [Float64[] Float64[]];
  PreTotalSumW = [Float64[] Float64[]];
  tmpn = nObs - rankX; ##zj::
  nPreRank = tmpn - 1
  partialSumWConst = Array{Float64}(nNullSimPts);
  totalSumWConst = Array{Float64}(nNullSimPts);
elseif longitudinal && fine == false
  QX = Xsvd[:U][:, 1 : rankX]
  QZsvd = svdfact(BLAS.gemm('T', 'N', XtNullBasis, Z))

  ZKeepIdx = (1 - QZsvd[:S]) .< 1e-6;
  rankQZ = countnz(ZKeepIdx)
  QZ = Array{Float64}(nObs, rankQZ);
  #orthonormal basis Q1 of C(Phi)-C(X)
  BLAS.gemm!('N', 'N', 1.0, Z, QZsvd[:V][:, 1 : rankQZ], 0.0, QZ);
  XPhitNullBasis = nullspace([QX Z]');
  tmpMat = Array{Float64}(rankQZ, size(Z,2));
  BLAS.gemm!('T', 'N', 1.0, QZ, Z, 0.0, tmpMat);
  PhiAdjsvd = svdfact(tmpMat, thin = false); #PhiAdjsvd ---WLambdaW'
  #W = PhiAdjsvd[:U]
  evalPhiAdj = PhiAdjsvd[:S] .^ 2
  # enforce first entry of each eigenvector to be >=0
  idxW = vec(PhiAdjsvd[:U][1, :]) .< 0
  PhiAdjsvd[:U][:, idxW] = - PhiAdjsvd[:U][:, idxW]

  KPhiAdj = PhiAdjsvd[:U][:, :]
  scale!(KPhiAdj, sqrt.(evalPhiAdj / minimum(evalPhiAdj) - 1))
  InvSqrtevalPhiAdj = similar(evalPhiAdj)
  for i = 1 : length(evalPhiAdj)
    InvSqrtevalPhiAdj[i] = 1 / sqrt(evalPhiAdj[i])
  end
  weightedW = PhiAdjsvd[:U][:, :]
  scale!(weightedW, InvSqrtevalPhiAdj)  ##weightedW---W'*Lambda^1/2
  yShift = QZ' * y   # precompute shift in Y

  # prepare for simulating Chi Squares and sums of Chi Squares
  tmpn = length(evalPhiAdj)
  nPreRank = tmpn -1
  QRes = Array{Float64}(nObs, rankQZ) # Q2
  tmpvec = similar(yShift)
  tmpvecQRes = Array{Float64}(rankQZ)
  yWork = similar(evalPhiAdj)
  partialSumWConst = Array{Float64}(nNullSimPts)
  totalSumWConst = Array{Float64}(nNullSimPts)
  subXPhitSV = Array{Float64}(size(XPhitNullBasis, 2), rankQZ)
  pSubXPhitSV = pointer(subXPhitSV)
  tmpMat = Array{Float64}(nObs, size(XPhitNullBasis, 2))
  VWorkSqrt = Array{Float64}(length(evalPhiAdj), nObs)
  VWorkSqrt2 = Array{Float64}(length(evalPhiAdj), nObs)

  BLAS.gemm!('T', 'N', 1.0, K, XPhitNullBasis, 0.0, tmpMat)
  (UXPhitS, svalXPhitS, VXPhitS) = svd(tmpMat, thin = false)
  rankXPhitS = countnz(svalXPhitS .> size(XPhitNullBasis, 2) * eps(svalXPhitS[1]))
  pXPhitSV = pointer(VXPhitS)
  BLAS.blascopy!(size(XPhitNullBasis, 2) * rankQZ, pXPhitSV, 1, pSubXPhitSV, 1)
  BLAS.gemm!('N', 'N', 1.0, XPhitNullBasis, subXPhitSV, 0.0, QRes) # QRes---Q2
  #working Y and working non-trivial variance component
  BLAS.blascopy!(length(yShift), yShift, 1, tmpvec, 1) # tmpvec---Q1'*y
  BLAS.gemv!('T', 1.0, QRes, y, 0.0, tmpvecQRes)  # tmpvecQRes---Q2'*y
  BLAS.gemv!('N', 1.0, KPhiAdj, tmpvecQRes, 1.0, tmpvec) #tmpvec---Q1'*y+K*Q2'*Y
  BLAS.gemv!('T', 1.0, weightedW, tmpvec, 0.0, yWork)
  BLAS.gemm!('T', 'N', 1.0, QZ, K, 0.0, VWorkSqrt2)  #VWorkSqrt2=Q1'*Kernel
  BLAS.gemm!('T', 'N', 1.0, weightedW, VWorkSqrt2, 0.0, VWorkSqrt)
  Vform = "half"
elseif fine
  QX = Xsvd[:U][:, 1 : rankX];  #99 4 #orthonormal basis of Q0 of C(X)
  Phieig = eigfact(Kadj);

  if typeof(Phieig[:values][1]) == Complex{Float64}
    Phieigval = reinterpret(Float64, Phieig[:values][1:2:end])
  else
    Phieigval = reinterpret(Float64, Phieig[:values][1:end])
  end

  Phieigvec = zeros(size(Phieig[:vectors]))
  if typeof(Phieig[:vectors][1,1]) == Complex{Float64}
    for p in 1:size(Phieigvec,1)
        Phieigvec[p,:] = reinterpret(Float64, Phieig[:vectors][p,:][1:2:end])
    end
  else
    for p in 1:size(Phieigvec,1)
        Phieigvec[p,:] = reinterpret(Float64, Phieig[:vectors][p,:][1:end])
    end
  end

  rankPhi = countnz(Phieigval .> max(0.0, nPerKeep * eps(maximum(Phieigval))));
  idxEvecPhi = vec(Phieigvec[1, :]) .< 0;
  scale!(Phieigvec[:, idxEvecPhi], -1.0);
  rankPhi = min(rankPhi, floor(rankPhi * lowRank));
  # low rank approximation
  sortIdx = sortperm(Phieigval, rev = true);
  evalPhi = Phieigval[sortIdx[1 : Int(rankPhi)]];
  evecPhi = Phieigvec[:, sortIdx[1 : Int(rankPhi)]];
  QPhisvd = svdfact(BLAS.gemm('T', 'N', XtNullBasis, evecPhi));
  PhiKeepIdx = (1 - QPhisvd[:S]) .< 1e-6;
  rankQPhi = countnz(PhiKeepIdx);
  #QPhi = evecPhi * QPhisvd[:V][:, 1 : rankQPhi];
  QPhi = Array{Float64}(nPerKeep, rankQPhi);
  BLAS.gemm!('N', 'N', 1.0, evecPhi, QPhisvd[:V][:, 1 : rankQPhi], 0.0, QPhi);
  XPhitNullBasis = nullspace([QX evecPhi]');
  tmpMat = Array{Float64}(rankQPhi, Int(rankPhi));

  BLAS.gemm!('T', 'N', 1.0, QPhi, evecPhi, 0.0, tmpMat);
  scale!(tmpMat, sqrt(evalPhi));
  PhiAdjsvd = svdfact(tmpMat, thin = false);
  evalPhiAdj = PhiAdjsvd[:S] .^ 2;
  idxW = vec(PhiAdjsvd[:U][1, :]) .< 0;
  scale!(PhiAdjsvd[:U][:, idxW], -1.0);
  KPhiAdj = PhiAdjsvd[:U][:, :];
  scale!(KPhiAdj, sqrt(evalPhiAdj / minimum(evalPhiAdj) - 1));
  InvSqrtevalPhiAdj = similar(evalPhiAdj);
  for i = 1 : length(evalPhiAdj)
    InvSqrtevalPhiAdj[i] = 1 / sqrt(evalPhiAdj[i]);
  end
  weightedW = PhiAdjsvd[:U][:, :];
  scale!(weightedW, InvSqrtevalPhiAdj);
  yShift = QPhi' * y;

  # prepare for simulating Chi Squares and sums of Chi Squares
  tmpn = length(evalPhiAdj);
  nPreRank = length(evalPhiAdj)-1
  QRes = Array{Float64}(nPerKeep, rankQPhi);

  tmpvec = similar(yShift);
  tmpvecQRes = Array{Float64}(rankQPhi);
  yWork = similar(evalPhiAdj);
  partialSumWConst = Array{Float64}(nNullSimPts);
  totalSumWConst = Array{Float64}(nNullSimPts);
  subXPhitSV = Array{Float64}(size(XPhitNullBasis, 2), rankQPhi);
  pSubXPhitSV = pointer(subXPhitSV);

  tmpMat = Array{Float64}(nPerKeep, size(XPhitNullBasis, 2));
  VWorkSqrt = Array{Float64}(length(evalPhiAdj), nPerKeep);
  VWorkSqrt2 = Array{Float64}(length(evalPhiAdj), nPerKeep);

     # obtain some orthonormal vectors of space R^n - [QX,QPHI,S]
     # See Golub and Van Loan (1996) Algorithm 12.4.2 on p602
  BLAS.gemm!('T', 'N', 1.0, K, XPhitNullBasis, 0.0, tmpMat);
  (UXPhitS, svalXPhitS, VXPhitS) = svd(tmpMat, thin = false);

  pXPhitSV = pointer(VXPhitS)
  BLAS.blascopy!(size(XPhitNullBasis, 2) * rankQPhi, pXPhitSV, 1, pSubXPhitSV, 1);
  BLAS.gemm!('N', 'N', 1.0, XPhitNullBasis, subXPhitSV, 0.0, QRes); # QRes---Q2
  BLAS.blascopy!(length(yShift), yShift, 1, tmpvec, 1); # tmpvec---Q1'*y
  BLAS.gemv!('T', 1.0, QRes, y, 0.0, tmpvecQRes);  # tmpvecQRes---Q2'*y
  BLAS.gemv!('N', 1.0, KPhiAdj, tmpvecQRes, 1.0, tmpvec); #tmpvec---Q1'*y+K*Q2'*Y
  BLAS.gemv!('T', 1.0, weightedW, tmpvec, 0.0, yWork);

  BLAS.gemm!('T', 'N', 1.0, QPhi, K, 0.0, VWorkSqrt2);  #VWorkSqrt2=Q1'*Kernel
  BLAS.gemm!('T', 'N', 1.0, weightedW, VWorkSqrt2, 0.0, VWorkSqrt);
  Vform="half"
end

if pvalueComputing == "chi2"
  nPtsChi2 = 300;
  partialSumW = Array{Float64}(nPtsChi2);
  totalSumW = Array{Float64}(nPtsChi2);
  lambda = Array{Float64}(1, nPtsChi2);
  W = Array{Float64}(tmpn, nPtsChi2);
  tmpmat0 = Array{Float64}(tmpn, nPtsChi2);
  tmpmat1 = Array{Float64}(tmpn, nPtsChi2);
  tmpmat2 = Array{Float64}(tmpn, nPtsChi2);
  tmpmat3 = Array{Float64}(tmpn, nPtsChi2);
  tmpmat4 = Array{Float64}(tmpn, nPtsChi2);
  tmpmat5 = Array{Float64}(tmpn, nPtsChi2);
  denomvec = Array{Float64}(nPtsChi2);
  d1f = Array{Float64}(nPtsChi2);
  d2f = Array{Float64}(nPtsChi2);
  if test == "eScore"
    simnull = Array{Float64}(nPtsChi2);
  else
    simnull = Float64[];
  end
else
  nPtsChi2 = 300;
  partialSumW = Array{Float64}(nNullSimPts);
  totalSumW = Array{Float64}(nNullSimPts);
  lambda = Array{Float64}(1, nNullSimPts);
  W = Array{Float64}(tmpn, nNullSimPts);
  tmpmat0 = Array{Float64}(tmpn, nNullSimPts);
  tmpmat1 = Array{Float64}(tmpn, nNullSimPts);
  tmpmat2 = Array{Float64}(tmpn, nNullSimPts);
  tmpmat3 = Array{Float64}(tmpn, nNullSimPts);
  tmpmat4 = Array{Float64}(tmpn, nNullSimPts);
  tmpmat5 = Array{Float64}(tmpn, nNullSimPts);
  denomvec = Array{Float64}(nNullSimPts);
  d1f = Array{Float64}(nNullSimPts);
  d2f = Array{Float64}(nNullSimPts);
  if test == "eScore"
    simnull = Array{Float64}(nNullSimPts);
  else
    simnull = Float64[];
  end
end

WPreSim = randn(nObs, nNullSimPts);
for idxWc = 1 : nNullSimPts
  for idxWr = 1 : nObs
    WPreSim[idxWr, idxWc] = WPreSim[idxWr, idxWc] * WPreSim[idxWr, idxWc];
  end
end

  # simulate Chi Squares and sums of Chi Squares
PrePartialSumW = Array{Float64}(nNullSimPts, nPreRank + 1);
PreTotalSumW = Array{Float64}(nNullSimPts, nPreRank + 1);
tmpSumVec = Array{Float64}(nNullSimPts);
p1 = pointer(PrePartialSumW);
BLAS.blascopy!(nNullSimPts, rand(Distributions.Chisq(tmpn), nNullSimPts), 1, p1, 1);
for i = 1 : nNullSimPts
  #pW = pointer(WPreSim) + (i - 1) * windowSize * sizeof(Float64);
  #tmpSumVec[i] = BLAS.asum(1, pW, 1);
  tmpSumVec[i] = 0.0;
  PreTotalSumW[i, 1] = tmpSumVec[i] + PrePartialSumW[i, 1];
end
for j = 1 : nPreRank
  p1 = pointer(PrePartialSumW) + j * nNullSimPts * sizeof(Float64)
  BLAS.blascopy!(nNullSimPts, rand(Distributions.Chisq(tmpn - j), nNullSimPts), 1, p1, 1);
  for i = 1 : nNullSimPts
    tmpSumVec[i] += WPreSim[j, i];
    PreTotalSumW[i, j+1] = tmpSumVec[i] + PrePartialSumW[i, j+1];
  end
end

if longitudinal == false && fine == false
     if test == "eRLRT"
        (b, vc0List, vc1List, pvalList) =
         vctest(ynew, [], XtNullBasis' * K , tests = test,
                Vform = "half", nBlockAscent = nBlockAscent, nMMmax = nMMmax,
                nNullSimPts = nNullSimPts, pvalueComputings = pvalueComputing,
                nNullSimNewtonIter = nNullSimNewtonIter, tolX = tolX,
                devices = device, PrePartialSumW = PrePartialSumW,
                PreTotalSumW = PreTotalSumW, partialSumWConst = partialSumWConst,
                totalSumWConst = totalSumWConst, windowSize = tmpn - 1,
                partialSumW = partialSumW, totalSumW = totalSumW,
                lambda = lambda, W = W, nPreRank = nPreRank, nPtsChi2=nPtsChi2,
                offset = offset);

     else
        (b, vc0List, vc1List, pvalList) =
         vctest(y, X, K,tests = test, WPreSim = WPreSim,
                Vform = "half", nBlockAscent = nBlockAscent, nMMmax = nMMmax,
                nNullSimPts = nNullSimPts, pvalueComputings = pvalueComputing,
                nNullSimNewtonIter = nNullSimNewtonIter, tolX = tolX,
                devices = device, PrePartialSumW = PrePartialSumW,
                PreTotalSumW = PreTotalSumW, partialSumWConst = partialSumWConst,
                totalSumWConst = totalSumWConst, windowSize = tmpn - 1,
                partialSumW = partialSumW, totalSumW = totalSumW,
                lambda = lambda, W = W, nPreRank = nPreRank, nPtsChi2=nPtsChi2,
                offset = offset);
     end
elseif longitudinal || fine
        (b, vc0List, vc1List, pvalList) =
         vctest(yWork, [], VWorkSqrt, tests = test, WPreSim = WPreSim,
                Vform = "half", nBlockAscent = nBlockAscent, nMMmax = nMMmax,
                nNullSimPts = nNullSimPts, pvalueComputings = pvalueComputing,
                nNullSimNewtonIter = nNullSimNewtonIter, tolX = tolX,
                devices = device, PrePartialSumW = PrePartialSumW,
                PreTotalSumW = PreTotalSumW, partialSumWConst = partialSumWConst,
                totalSumWConst = totalSumWConst, windowSize = tmpn - 1,
                partialSumW = partialSumW, totalSumW = totalSumW,
                lambda = lambda, W = W, nPreRank = nPreRank, nPtsChi2=nPtsChi2,
                offset = offset);
end

if out == true
#  outresults = vcat(vc0List, vc1List, pvalList)
  outrlst = hcat(yname, vcat(vc0List, vc1List, pvalList)')
  cname = hcat("phenotye", "vc0", "vc1", "pvalue")
  outrlst = [cname; outrlst]
  writedlm(outFile, outrlst)
end

return b, vc0List, vc1List, pvalList
end