diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index cba9134..5577817 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -1,16 +1,43 @@ -name: CompatHelper on: schedule: - cron: 0 0 * * * workflow_dispatch: +permissions: + contents: write + pull-requests: write jobs: CompatHelper: runs-on: ubuntu-latest steps: - - name: Pkg.add("CompatHelper") - run: julia -e 'using Pkg; Pkg.add("CompatHelper")' - - name: CompatHelper.main() + - name: Check if Julia is already available in the PATH + id: julia_in_path + run: which julia + continue-on-error: true + - name: Install Julia, but only if it is not already available in the PATH + uses: julia-actions/setup-julia@v1 + with: + version: "1" + arch: ${{ runner.arch }} + if: steps.julia_in_path.outcome != 'success' + - name: "Add the General registry via Git" + run: | + import Pkg + ENV["JULIA_PKG_SERVER"] = "" + Pkg.Registry.add("General") + shell: julia --color=yes {0} + - name: "Install CompatHelper" + run: | + import Pkg + name = "CompatHelper" + uuid = "aa819f21-2bde-4658-8897-bab36330d9b7" + version = "3" + Pkg.add(; name, uuid, version) + shell: julia --color=yes {0} + - name: "Run CompatHelper" + run: | + import CompatHelper + CompatHelper.main() + shell: julia --color=yes {0} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} - run: julia -e 'using CompatHelper; CompatHelper.main()' diff --git a/.github/workflows/SpellCheck.yml b/.github/workflows/SpellCheck.yml new file mode 100644 index 0000000..ed4fe17 --- /dev/null +++ b/.github/workflows/SpellCheck.yml @@ -0,0 +1,13 @@ +name: Spell Check + +on: [pull_request] + +jobs: + typos-check: + name: Spell Check with Typos + runs-on: ubuntu-latest + steps: + - name: Checkout Actions Repository + uses: actions/checkout@v4 + - name: Check spelling + uses: crate-ci/typos@v1.18.0 diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index 623860f..0cd3114 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -4,6 +4,22 @@ on: types: - created workflow_dispatch: + inputs: + lookback: + default: "3" +permissions: + actions: read + checks: read + contents: write + deployments: read + issues: read + discussions: read + packages: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read jobs: TagBot: if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' @@ -12,4 +28,4 @@ jobs: - uses: JuliaRegistries/TagBot@v1 with: token: ${{ secrets.GITHUB_TOKEN }} - ssh: ${{ secrets.DOCUMENTER_KEY }} \ No newline at end of file + ssh: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f3fb23..2fd83f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,16 +1,48 @@ name: CI on: + pull_request: + branches: + - main + - dev + paths-ignore: + - "docs/**" push: branches: - main - tags: '*' - pull_request: -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} + paths-ignore: + - "docs/**" jobs: + formatter: + runs-on: ${{ matrix.os }} + strategy: + matrix: + julia-version: [1] + julia-arch: [x86] + os: [ubuntu-latest] + steps: + - uses: julia-actions/setup-julia@latest + with: + version: ${{ matrix.julia-version }} + + - uses: actions/checkout@v4 + - name: Install JuliaFormatter and format + # This will use the latest version by default but you can set the version like so: + # + # julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter", version="0.13.0"))' + run: | + julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter", version="1.0.50"))' + julia -e 'using JuliaFormatter; format(".", verbose=true)' + - name: Format check + run: | + julia -e ' + out = Cmd(`git diff`) |> read |> String + if out == "" + exit(0) + else + @error "Some files have not been formatted !!!" + write(stdout, out) + exit(1) + end' test: name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} runs-on: ${{ matrix.os }} @@ -18,29 +50,32 @@ jobs: fail-fast: false matrix: version: - - "1.10" - - 'nightly' + - "1.8" + - "1" # automatically expands to the latest stable 1.x release of Julia + - nightly os: - ubuntu-latest - - macOS-latest - - windows-latest arch: - x64 - x86 - threads: - - "2" - exclude: + include: + # test macOS and Windows with latest Julia only - os: macOS-latest - arch: x86 + arch: x64 + version: 1 + - os: windows-latest + arch: x64 + version: 1 - os: windows-latest arch: x86 + version: 1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v1 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 + - uses: actions/cache@v4 env: cache-name: cache-artifacts with: @@ -52,31 +87,30 @@ jobs: ${{ runner.os }}- - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - env: - JULIA_NUM_THREADS: ${{ matrix.threads }} - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v4 with: file: lcov.info - docs: - name: Documentation - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: julia-actions/setup-julia@v1 - with: - version: "1" - - run: | - julia --project=docs -e ' - using Pkg - Pkg.develop(PackageSpec(path=pwd())) - Pkg.instantiate()' - - run: | - julia --project=docs -e ' - using Documenter: doctest - using CompositionalNetworks - doctest(CompositionalNetworks)' - - run: julia --project=docs docs/make.jl - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} + # docs: + # name: Documentation + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - uses: julia-actions/setup-julia@v1 + # with: + # version: "1" + # - run: | + # julia --project=docs -e ' + # using Pkg + # Pkg.develop(PackageSpec(path=pwd())) + # Pkg.instantiate()' + # - run: | + # julia --project=docs -e ' + # using Documenter: DocMeta, doctest + # using CompositionalNetworks + # DocMeta.setdocmeta!(CompositionalNetworks, :DocTestSetup, :(using CompositionalNetworks); recursive=true) + # doctest(CompositionalNetworks)' + # - run: julia --project=docs docs/make.jl + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.github/workflows/register.yml b/.github/workflows/register.yml new file mode 100644 index 0000000..5b7cd3b --- /dev/null +++ b/.github/workflows/register.yml @@ -0,0 +1,16 @@ +name: Register Package +on: + workflow_dispatch: + inputs: + version: + description: Version to register or component to bump + required: true +jobs: + register: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: julia-actions/RegisterAction@latest + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Project.toml b/Project.toml index 6baa896..885221d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "CompositionalNetworks" uuid = "4b67e4b5-442d-4ef5-b760-3f5df3a57537" authors = ["Jean-François Baffier"] -version = "0.5.5" +version = "0.5.6" [deps] ConstraintCommons = "e37357d9-0691-492f-a822-e5ea6a920954" @@ -17,12 +17,13 @@ ThreadSafeDicts = "4239201d-c60e-5e0a-9702-85d713665ba7" Unrolled = "9602ed7d-8fef-5bc8-8597-8f21381861e8" [compat] -ConstraintCommons = "0.1" +ConstraintCommons = "0.2" ConstraintDomains = "0.3" Dictionaries = "0.4" Distances = "0.10" -JuliaFormatter = "0.22, 1" +JuliaFormatter = "1" OrderedCollections = "1" +Random = "1" TestItemRunner = "0.2" TestItems = "0.1" ThreadSafeDicts = "0.1" @@ -30,7 +31,11 @@ Unrolled = "0.1" julia = "1.8" [extras] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +Evolutionary = "86b6b26d-c046-49b6-aa0b-5f0f74682bd6" +Memoization = "6fafb56a-5788-4b4e-91ca-c0cea6611c73" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +ThreadPools = "b189fb0b-2eb5-4ed4-bc0c-d34c51242431" [targets] -test = ["Test"] +test = ["Aqua", "Evolutionary", "Memoization", "Test", "ThreadPools"] diff --git a/docs/Project.toml b/docs/Project.toml deleted file mode 100644 index 2146e07..0000000 --- a/docs/Project.toml +++ /dev/null @@ -1,4 +0,0 @@ -[deps] -CompositionalNetworks = "4b67e4b5-442d-4ef5-b760-3f5df3a57537" -ConstraintDomains = "5800fd60-8556-4464-8d61-84ebf7a0bedb" -Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" diff --git a/docs/make.jl b/docs/make.jl deleted file mode 100644 index e17262e..0000000 --- a/docs/make.jl +++ /dev/null @@ -1,38 +0,0 @@ -using CompositionalNetworks -using ConstraintDomains -using Documenter - -makedocs(; - modules=[CompositionalNetworks, ConstraintDomains], - authors="Jean-François Baffier", - repo="https://github.com/JuliaConstraints/CompositionalNetworks.jl/blob/{commit}{path}#L{line}", - sitename="CompositionalNetworks.jl", - format=Documenter.HTML(; - prettyurls=get(ENV, "CI", nothing) == "true", - canonical="https://JuliaConstraints.github.io/CompositionalNetworks.jl", - assets = ["assets/favicon.ico"; "assets/github_buttons.js"; "assets/custom.css"], - ), - pages=[ - "Home" => "index.md", - "ICNs" => "icn.md", - "Layers" => [ - "Transformation" => "transformation.md", - "Arithmetic" => "arithmetic.md", - "Aggregation" => "aggregation.md", - "Comparison" => "comparison.md", - ], - "Dependencies" => [ - "ConstraintDomains.jl" => "domain.md", - ], - "Library" => [ - "public.md", - "internal.md", - ], - ], -) - -deploydocs(; - repo="github.com/JuliaConstraints/CompositionalNetworks.jl.git", - devbranch="main", -) - diff --git a/docs/src/aggregation.md b/docs/src/aggregation.md deleted file mode 100644 index 498eb07..0000000 --- a/docs/src/aggregation.md +++ /dev/null @@ -1,17 +0,0 @@ -# Aggregation Layer - -The aggregation layer of our basic ICN can be constructed using `aggregation_layer()`. - - -```@docs -CompositionalNetworks.aggregation_layer -``` - -## List of Aggregations - -Follows a list of the current operations available in any aggregation layer. Those operations are mutually exclusive. - -```@docs -CompositionalNetworks._ag_sum -CompositionalNetworks._ag_count_positive -``` diff --git a/docs/src/arithmetic.md b/docs/src/arithmetic.md deleted file mode 100644 index a2a3c75..0000000 --- a/docs/src/arithmetic.md +++ /dev/null @@ -1,17 +0,0 @@ -# Arithmetic Layer - -The arithmetic layer of our basic ICN can be constructed using `arithmetic_layer()`. - - -```@docs -CompositionalNetworks.arithmetic_layer -``` - -## List of Arithmetic operations - -Follows a list of the current operations available in any arithmetic layer. Those operations are mutually exclusive. - -```@docs -CompositionalNetworks._ar_sum -CompositionalNetworks._ar_prod -``` diff --git a/docs/src/comparison.md b/docs/src/comparison.md deleted file mode 100644 index b7f8222..0000000 --- a/docs/src/comparison.md +++ /dev/null @@ -1,30 +0,0 @@ -# Comparison Layer - -The comparison layer of our basic ICN can be constructed using `comparison_layer(param=false)`. All operations are mutually exclusive. - -```@docs -CompositionalNetworks.comparison_layer -``` - -## Non-parametric comparisons - -Follows a list of the current non-parametric operations available in any comparison layer. - -```@docs -CompositionalNetworks._co_identity -CompositionalNetworks._co_euclidian -CompositionalNetworks._co_abs_diff_val_vars -CompositionalNetworks._co_val_minus_vars -CompositionalNetworks._co_vars_minus_val -``` - -## Parametric comparisons - -And finally a list of the parametric ones. - -```@docs -CompositionalNetworks._co_abs_diff_val_param -CompositionalNetworks._co_val_minus_param -CompositionalNetworks._co_param_minus_val -CompositionalNetworks._co_euclidian_param -``` \ No newline at end of file diff --git a/docs/src/domain.md b/docs/src/domain.md deleted file mode 100644 index fb6cc57..0000000 --- a/docs/src/domain.md +++ /dev/null @@ -1,7 +0,0 @@ -# ConstraintDomains.jl (dependency) - -Currently only discrete domains are supported using the following function. - -```@docs -ConstraintDomains.domain -``` diff --git a/docs/src/icn.md b/docs/src/icn.md deleted file mode 100644 index 3eb6d2e..0000000 --- a/docs/src/icn.md +++ /dev/null @@ -1,7 +0,0 @@ -# ICNs - -Currently only construct a generic ICN with all available operations. - -```@docs -CompositionalNetworks.ICN -``` \ No newline at end of file diff --git a/docs/src/index.md b/docs/src/index.md deleted file mode 100644 index 112bb05..0000000 --- a/docs/src/index.md +++ /dev/null @@ -1,62 +0,0 @@ -```@meta -CurrentModule = CompositionalNetworks -``` - -# CompositionalNetworks.jl - -`CompositionalNetworks.jl`, a Julia package for Interpretable Compositional Networks (ICN), a variant of neural networks, allowing the user to get interpretable results, unlike regular artificial neural networks. - -The current state of our ICN focuses on the composition of error functions for `LocalSearchSolvers.jl`, but produces results independently of it and export it to either/both Julia functions or/and human readable output. - -### How does it work? - -The package comes with a basic ICN for learning global constraints. The ICN is composed of 4 layers: `transformation`, `arithmetic`, `aggregation`, and `comparison`. Each contains several operations that can be composed in various ways. -Given a `concept` (a predicate over the variables' domains), a metric (`hamming` by default), and the variables' domains, we learn the binary weights of the ICN. - -## Installation - -```julia -] add CompositionalNetworks -``` - -As the package is in a beta version, some changes in the syntax and features are likely to occur. However, those changes should be minimal between minor versions. Please update with caution. - -## Quickstart - -```julia -# 4 variables in 1:4 -doms = [domain([1,2,3,4]) for i in 1:4] - -# allunique concept (that is used to define the :all_different constraint) -err = explore_learn_compose(allunique, domains=doms) -# > interpretation: identity ∘ count_positive ∘ sum ∘ count_eq_left - -# test our new error function -@assert err([1,2,3,3], dom_size = 4) > 0.0 - -# export an all_different function to file "current/path/test_dummy.jl" -compose_to_file!(icn, "all_different", "test_dummy.jl") -``` - -The output file should produces a function that can be used as follows (assuming the maximum domain size is `7`) - -```julia -import CompositionalNetworks - -all_different([1,2,3,4,5,6,7]; dom_size = 7) -# > 0.0 (which means true, no errors) -``` - -Please see `JuliaConstraints/Constraints.jl/learn.jl` for an extensive example of ICN learning and compositions. - -## Contributing - -Contributions to this package are more than welcome and can be arbitrarily, and not exhaustively, split as follows: -- Adding (useful) operations in one of the $4$ existing layers -- Creating other ICNs from scratch or with only some of the original operations -- Creating an ICN with a layer structure -- Creating other compositional networks which target other problems -- Just making stuff better, faster, user-friendlier, etc. - -### Contact -Do not hesitate to contact me (@azzaare) or other members of JuliaConstraints on GitHub (file an issue), the julialang discourse forum, the julialang slack channel, the julialang zulip server, or the Human of Julia (HoJ) discord server. \ No newline at end of file diff --git a/docs/src/internal.md b/docs/src/internal.md deleted file mode 100644 index 11ed5a6..0000000 --- a/docs/src/internal.md +++ /dev/null @@ -1,11 +0,0 @@ -# Internals - -```@contents -Pages = ["internal.md"] -Depth = 5 -``` - -```@autodocs -Modules = [CompositionalNetworks] -Public = false -``` diff --git a/docs/src/public.md b/docs/src/public.md deleted file mode 100644 index 13f305a..0000000 --- a/docs/src/public.md +++ /dev/null @@ -1,11 +0,0 @@ -# Public - -```@contents -Pages = ["public.md"] -Depth = 5 -``` - -```@autodocs -Modules = [CompositionalNetworks] -Private = false -``` diff --git a/docs/src/transformation.md b/docs/src/transformation.md deleted file mode 100644 index 4d0024c..0000000 --- a/docs/src/transformation.md +++ /dev/null @@ -1,52 +0,0 @@ -# Transformation Layer - -The transformation layer of our basic ICN can be constructed using `transformation_layer(param=false)`. - - -```@docs -CompositionalNetworks.transformation_layer -``` - -## Non-parametric transformations - -Follows a list of the current non-parametric operations available in any transformation layer. - -```@docs -CompositionalNetworks._tr_identity -CompositionalNetworks._tr_count_eq -CompositionalNetworks._tr_count_eq_left -CompositionalNetworks._tr_count_eq_right -CompositionalNetworks._tr_count_greater -CompositionalNetworks._tr_count_lesser -CompositionalNetworks._tr_count_g_left -CompositionalNetworks._tr_count_l_left -CompositionalNetworks._tr_count_g_right -CompositionalNetworks._tr_count_l_right -CompositionalNetworks._tr_contiguous_vals_minus -CompositionalNetworks._tr_contiguous_vals_minus_rev -``` - -Note that all functions are extended to a vectorized version with the `lazy` function. - -```@docs -CompositionalNetworks.lazy -``` - -## Parametric transformations - -And finally a list of the parametric ones. - -```@docs -CompositionalNetworks._tr_count_eq_param -CompositionalNetworks._tr_count_l_param -CompositionalNetworks._tr_count_g_param -CompositionalNetworks._tr_count_bounding_param -CompositionalNetworks._tr_val_minus_param -CompositionalNetworks._tr_param_minus_val -``` - -Note that all functions are extended to a vectorized version with the `lazy_param` function. - -```@docs -CompositionalNetworks.lazy_param -``` \ No newline at end of file diff --git a/paper/.latexmkrc b/paper/.latexmkrc deleted file mode 100644 index ddcb138..0000000 --- a/paper/.latexmkrc +++ /dev/null @@ -1,6 +0,0 @@ - -sub build_header { - system("ruby ./prep.rb") -} - -build_header() diff --git a/paper/bib.tex b/paper/bib.tex deleted file mode 100644 index 8e1819a..0000000 --- a/paper/bib.tex +++ /dev/null @@ -1,4 +0,0 @@ -% **************GENERATED FILE, DO NOT EDIT************** - -\bibliographystyle{juliacon} -\bibliography{ref.bib} diff --git a/paper/figs/csp_landscape_complex_zero_big.png b/paper/figs/csp_landscape_complex_zero_big.png deleted file mode 100644 index fc75089..0000000 Binary files a/paper/figs/csp_landscape_complex_zero_big.png and /dev/null differ diff --git a/paper/figs/efsp_landscape_complex_zero_big.png b/paper/figs/efsp_landscape_complex_zero_big.png deleted file mode 100644 index e7bdbd8..0000000 Binary files a/paper/figs/efsp_landscape_complex_zero_big.png and /dev/null differ diff --git a/paper/figs/juliaconstraints.png b/paper/figs/juliaconstraints.png deleted file mode 100644 index 4a1302e..0000000 Binary files a/paper/figs/juliaconstraints.png and /dev/null differ diff --git a/paper/figs/magicsquare.pdf b/paper/figs/magicsquare.pdf deleted file mode 100644 index 427db98..0000000 Binary files a/paper/figs/magicsquare.pdf and /dev/null differ diff --git a/paper/figs/magicsquare.svg b/paper/figs/magicsquare.svg deleted file mode 100644 index cd0e669..0000000 --- a/paper/figs/magicsquare.svg +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/paper/figs/model_nn.png b/paper/figs/model_nn.png deleted file mode 100644 index f4c7fe4..0000000 Binary files a/paper/figs/model_nn.png and /dev/null differ diff --git a/paper/figs/overview.pdf b/paper/figs/overview.pdf deleted file mode 100644 index c00142d..0000000 Binary files a/paper/figs/overview.pdf and /dev/null differ diff --git a/paper/header.tex b/paper/header.tex deleted file mode 100644 index 6652609..0000000 --- a/paper/header.tex +++ /dev/null @@ -1,23 +0,0 @@ -% **************GENERATED FILE, DO NOT EDIT************** - -\title{CompositionalNetworks.jl: a scaling glass-box neural network to learn combinatorial functions} - -\author[1]{Jean-François \textsc{Baffier}} -\author[2]{Khalil \textsc{Chrit}} -\author[3,4]{Florian \textsc{Richoux}} -\author[2]{Pedro \textsc{Patinho}} -\author[2]{Salvador \textsc{Abreu}} -\affil[1]{IIJ, Japan} -\affil[2]{NOVA-LINCS, University of Évora, Portugal} -\affil[3]{AIST, Japan} -\affil[4]{JFLI, CNRS, Japan} - -\keywords{Julia Language, Constraint Programming, Local Search, Metaheuristics, Neural Network, Metaprogramming, Scalable Machine Learning, Glass-Box Algorithm} - -\hypersetup{ -pdftitle = {CompositionalNetworks.jl: a scaling glass-box neural network to learn combinatorial functions}, -pdfsubject = {JuliaCon 2019 Proceedings}, -pdfauthor = {Jean-François \textsc{Baffier}, Khalil \textsc{Chrit}, Florian \textsc{Richoux}, Pedro \textsc{Patinho}, Salvador \textsc{Abreu}}, -pdfkeywords = {Julia Language, Constraint Programming, Local Search, Metaheuristics, Neural Network, Metaprogramming, Scalable Machine Learning, Glass-Box Algorithm}, -} - diff --git a/paper/jlcode.sty b/paper/jlcode.sty deleted file mode 100644 index affd6a3..0000000 --- a/paper/jlcode.sty +++ /dev/null @@ -1,420 +0,0 @@ -%% -%% Julia definition (c) 2018 by wg030 -%% -%% -%% -% keywords, literals and built-ins from: -% https://github.com/isagalaev/highlight.js/blob/master/src/languages/julia.js -% colors from: -% https://docs.julialang.org/en/stable/assets/highlightjs/default.css -% https://docs.julialang.org/en/stable/assets/documenter.css -% special unicode characters from: -% https://docs.julialang.org/en/stable/manual/unicode-input/ - - - - - -% defining the jlcode package -\def\fileversion{2.1} -\def\filedate{2018/03/06} - -\typeout{-- Package: `jlcode' \fileversion\space <\filedate> --} -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{jlcode}[\filedate\space\fileversion] - - - - - -% loading required packages -\RequirePackage{listings} -\RequirePackage{xcolor} % for coloring -\RequirePackage{textcomp} % for upright single quotes -\RequirePackage{amssymb} % for the ϰ symbol -\RequirePackage{eurosym} % for the € symbol -\PassOptionsToPackage{T1}{fontenc} -\RequirePackage{fontenc} % for the « and » symbols -\RequirePackage{calc} % for the creation of the code box - - - - - -% julia language definition -\lstdefinelanguage{julia} -{% -% -% julia's keywords: -% -morekeywords=[1] -{% -in,isa,where,baremodule,begin,break,catch,ccall,const,continue,do,else,elseif,% -end,export,finally,for,function,global,if,import,importall,let,local,macro,% -module,quote,return,try,using,while,struct,mutable,primitive,% -% legacy, to be deprecated in the next release -type,immutable,abstract,bitstype,typealias% -},% -% -% julia's literals: -% -morekeywords=[2] -{% -true,false,ARGS,C_NULL,DevNull,ENDIAN_BOM,ENV,I,Inf,Inf16,Inf32,Inf64,% -InsertionSort,JULIA_HOME,LOAD_PATH,MergeSort,NaN,NaN16,NaN32,NaN64,% -PROGRAM_FILE,QuickSort,RoundDown,RoundFromZero,RoundNearest,% -RoundNearestTiesAway,RoundNearestTiesUp,RoundToZero,RoundUp,STDERR,STDIN,% -STDOUT,VERSION,catalan,e,eu,eulergamma,golden,im,nothing,pi,γ,π,φ% -},% -% -% julia's built-ins: -% -morekeywords=[3] -{% -ANY,AbstractArray,AbstractChannel,AbstractFloat,AbstractMatrix,AbstractRNG,% -AbstractSerializer,AbstractSet,AbstractSparseArray,AbstractSparseMatrix,% -AbstractSparseVector,AbstractString,AbstractUnitRange,AbstractVecOrMat,% -AbstractVector,Any,ArgumentError,Array,AssertionError,Associative,% -Base64DecodePipe,Base64EncodePipe,Bidiagonal,BigFloat,BigInt,BitArray,% -BitMatrix,BitVector,Bool,BoundsError,BufferStream,CachingPool,% -CapturedException,CartesianIndex,CartesianRange,Cchar,Cdouble,Cfloat,Channel,% -Char,Cint,Cintmax_t,Clong,Clonglong,ClusterManager,Cmd,CodeInfo,Colon,Complex,% -Complex128,Complex32,Complex64,CompositeException,Condition,ConjArray,% -ConjMatrix,ConjVector,Cptrdiff_t,Cshort,Csize_t,Cssize_t,Cstring,Cuchar,Cuint,% -Cuintmax_t,Culong,Culonglong,Cushort,Cwchar_t,Cwstring,DataType,Date,% -DateFormat,DateTime,DenseArray,DenseMatrix,DenseVecOrMat,DenseVector,Diagonal,% -Dict,DimensionMismatch,Dims,DirectIndexString,Display,DivideError,DomainError,% -EOFError,EachLine,Enum,Enumerate,ErrorException,Exception,ExponentialBackOff,% -Expr,Factorization,FileMonitor,Float16,Float32,Float64,Function,Future,% -GlobalRef,GotoNode,HTML,Hermitian,IO,IOBuffer,IOContext,IOStream,IPAddr,IPv4,% -IPv6,IndexCartesian,IndexLinear,IndexStyle,InexactError,InitError,Int,Int128,% -Int16,Int32,Int64,Int8,IntSet,Integer,InterruptException,InvalidStateException,% -Irrational,KeyError,LabelNode,LinSpace,LineNumberNode,LoadError,% -LowerTriangular,MIME,Matrix,MersenneTwister,Method,MethodError,MethodTable,% -Module,NTuple,NewvarNode,NullException,Nullable,Number,ObjectIdDict,% -OrdinalRange,OutOfMemoryError,OverflowError,Pair,ParseError,PartialQuickSort,% -PermutedDimsArray,Pipe,PollingFileWatcher,ProcessExitedException,Ptr,QuoteNode,% -RandomDevice,Range,RangeIndex,Rational,RawFD,ReadOnlyMemoryError,Real,% -ReentrantLock,Ref,Regex,RegexMatch,RemoteChannel,RemoteException,RevString,% -RoundingMode,RowVector,SSAValue,SegmentationFault,SerializationState,Set,% -SharedArray,SharedMatrix,SharedVector,Signed,SimpleVector,Slot,SlotNumber,% -SparseMatrixCSC,SparseVector,StackFrame,StackOverflowError,StackTrace,% -StepRange,StepRangeLen,StridedArray,StridedMatrix,StridedVecOrMat,% -StridedVector,String,SubArray,SubString,SymTridiagonal,Symbol,Symmetric,% -SystemError,TCPSocket,Task,Text,TextDisplay,Timer,Tridiagonal,Tuple,Type,% -TypeError,TypeMapEntry,TypeMapLevel,TypeName,TypeVar,TypedSlot,UDPSocket,UInt,% -UInt128,UInt16,UInt32,UInt64,UInt8,UndefRefError,UndefVarError,UnicodeError,% -UniformScaling,Union,UnionAll,UnitRange,Unsigned,UpperTriangular,Val,Vararg,% -VecElement,VecOrMat,Vector,VersionNumber,Void,WeakKeyDict,WeakRef,WorkerConfig,% -WorkerPool% -},% -% -% -sensitive=true,% -% -alsoother={$},%$ -% -morecomment=[l]{\#},% -morecomment=[n]{\#=}{=\#},% -% -morestring=[b]{"},% -morestring=[m]{'},% -morestring=[s]{"""}{"""},% -morestring=[s]{r"}{"},% -morestring=[s]{b"}{"},% -morestring=[s]{v"}{"},% -morestring=[s]{raw"}{"},% -morestring=[s]{L"}{"},% -% -}[keywords,comments,strings] - - -% defining the colors for -\definecolor{jlbase}{rgb}{.28,.28,.28} % julia's base color -\definecolor{jlkeyword}{rgb}{0.4, 0.0, 0.3} % julia's keywords -\definecolor{jlliteral}{HTML}{78A960} % julia's literals -\definecolor{jlbuiltin}{HTML}{397300} % julia's built-ins -\definecolor{jlcomment}{HTML}{888888} % julia's comments -\definecolor{jlstring}{HTML}{880000} % julia's strings -\definecolor{jlbackground}{HTML}{F5F5F5} % the background of the code block -\definecolor{jlrule}{HTML}{DDDDDD} % the rule of the code block - - -% defining the ucc and the ucclit command -% for literating special unicode characters -\newcommand{\ucc}[1]{% -\ifnum\lst@mode=\lst@Pmode\relax% -{\color{jlbase}#1}% -\else% -#1% -\fi% -} - -\newcommand{\ucclit}[1]{% -\ifnum\lst@mode=\lst@Pmode\relax% -{\color{jlliteral}#1}% -\else% -#1% -\fi% -} - - -% defining a new opliterate key -\def\lst@OpLiteratekey#1\@nil@{\let\lst@ifxopliterate\lst@if - \def\lst@opliterate{#1}} -\lst@Key{opliterate}{}{\@ifstar{\lst@true \lst@OpLiteratekey} - {\lst@false\lst@OpLiteratekey}#1\@nil@} -\lst@AddToHook{SelectCharTable} - {\ifx\lst@opliterate\@empty\else - \expandafter\lst@OpLiterate\lst@opliterate{}\relax\z@ - \fi} -\def\lst@OpLiterate#1#2#3{% - \ifx\relax#2\@empty\else - \lst@CArgX #1\relax\lst@CDef - {} - {\let\lst@next\@empty - \lst@ifxopliterate - \lst@ifmode \let\lst@next\lst@CArgEmpty \fi - \fi - \ifx\lst@next\@empty - \ifx\lst@OutputBox\@gobble\else - \lst@XPrintToken \let\lst@scanmode\lst@scan@m - \lst@token{#2}\lst@length#3\relax - \lst@XPrintToken - \fi - \let\lst@next\lst@CArgEmptyGobble - \fi - \lst@next}% - \@empty - \expandafter\lst@OpLiterate - \fi} - - -% defining the \addlitjlbase and \addlitjlstring commands, -% which help a user to fix some of the known managable issues -\def\addToLiterate#1{% -\protected@edef\lst@literate{% -\unexpanded\expandafter{\lst@literate}\unexpanded{#1}}} -\lst@Key{expandliterate}{}{\addToLiterate{#1}} -\newcommand{\addlitjlbase}[3]{% -\lstset{expandliterate={#1}{{{\color{jlbase}#2}}}{#3}}} -\newcommand{\addlitjlstring}[3]{% -\lstset{expandliterate={#1}{{{\color{jlstring}#2}}}{#3}}} - - - - - -% defining the styles for -\lstset{keywordstyle={[1]\color{jlkeyword}\bfseries}} % julia's keywords -\lstset{keywordstyle={[2]\color{jlliteral}}} % julia's literals -\lstset{keywordstyle={[3]\color{jlbuiltin}}} % julia's built-ins -\lstset{commentstyle={\color{jlcomment}}} % julia's comments -\lstset{stringstyle={\color{jlstring}}} % julia's strings -\lstset{identifierstyle={\color{jlbase}}} % julia's identifiers - - -\lstset{opliterate=* -% -% julia's operators -% -{\\}{{{\color{jlbase}\lstum@backslash}}}{1} {\{}{{{\color{jlbase}\{}}}{1} -{\}}{{{\color{jlbase}\}}}}{1} {!}{{{\color{jlbase}!}}}{1} -{\%}{{{\color{jlbase}\%}}}{1} {&}{{{\color{jlbase}\&}}}{1} -{(}{{{\color{jlbase}(}}}{1} {)}{{{\color{jlbase})}}}{1} -{*}{{{\color{jlbase}*}}}{1} {+}{{{\color{jlbase}+}}}{1} -{,}{{{\color{jlbase},}}}{1} {-}{{{\color{jlbase}-}}}{1} -{.}{{{\color{jlbase}.}}}{1} {/}{{{\color{jlbase}/}}}{1} -{:}{{{\color{jlbase}:}}}{1} {;}{{{\color{jlbase};}}}{1} -{<}{{{\color{jlbase}<}}}{1} {=}{{{\color{jlbase}=}}}{1} -{>}{{{\color{jlbase}>}}}{1} {?}{{{\color{jlbase}?}}}{1} -{[}{{{\color{jlbase}[}}}{1} {]}{{{\color{jlbase}]}}}{1} -{^}{{{\color{jlbase}\^{}}}}{1} {|}{{{\color{jlbase}|}}}{1} -{~}{{{\color{jlbase}\textasciitilde{}}}}{1} -% -% julia's numbers -% -{.0}{{{\color{jlstring}.0}}}{2} {.1}{{{\color{jlstring}.1}}}{2} -{.2}{{{\color{jlstring}.2}}}{2} {.3}{{{\color{jlstring}.3}}}{2} -{.4}{{{\color{jlstring}.4}}}{2} {.5}{{{\color{jlstring}.5}}}{2} -{.6}{{{\color{jlstring}.6}}}{2} {.7}{{{\color{jlstring}.7}}}{2} -{.8}{{{\color{jlstring}.8}}}{2} {.9}{{{\color{jlstring}.9}}}{2} -% -{e+0}{{{\color{jlstring}e+0}}}{3} {e+1}{{{\color{jlstring}e+1}}}{3} -{e+2}{{{\color{jlstring}e+2}}}{3} {e+3}{{{\color{jlstring}e+3}}}{3} -{e+4}{{{\color{jlstring}e+4}}}{3} {e+5}{{{\color{jlstring}e+5}}}{3} -{e+6}{{{\color{jlstring}e+6}}}{3} {e+7}{{{\color{jlstring}e+7}}}{3} -{e+8}{{{\color{jlstring}e+8}}}{3} {e+9}{{{\color{jlstring}e+9}}}{3} -% -{0E+}{{{\color{jlstring}0E+}}}{3} {1E+}{{{\color{jlstring}1E+}}}{3} -{2E+}{{{\color{jlstring}2E+}}}{3} {3E+}{{{\color{jlstring}3E+}}}{3} -{4E+}{{{\color{jlstring}4E+}}}{3} {5E+}{{{\color{jlstring}5E+}}}{3} -{6E+}{{{\color{jlstring}6E+}}}{3} {7E+}{{{\color{jlstring}7E+}}}{3} -{8E+}{{{\color{jlstring}8E+}}}{3} {9E+}{{{\color{jlstring}9E+}}}{3} -% -{e-0}{{{\color{jlstring}e-0}}}{3} {e-1}{{{\color{jlstring}e-1}}}{3} -{e-2}{{{\color{jlstring}e-2}}}{3} {e-3}{{{\color{jlstring}e-3}}}{3} -{e-4}{{{\color{jlstring}e-4}}}{3} {e-5}{{{\color{jlstring}e-5}}}{3} -{e-6}{{{\color{jlstring}e-6}}}{3} {e-7}{{{\color{jlstring}e-7}}}{3} -{e-8}{{{\color{jlstring}e-8}}}{3} {e-9}{{{\color{jlstring}e-9}}}{3} -% -{0E-}{{{\color{jlstring}0E-}}}{3} {1E-}{{{\color{jlstring}1E-}}}{3} -{2E-}{{{\color{jlstring}2E-}}}{3} {3E-}{{{\color{jlstring}3E-}}}{3} -{4E-}{{{\color{jlstring}4E-}}}{3} {5E-}{{{\color{jlstring}5E-}}}{3} -{6E-}{{{\color{jlstring}6E-}}}{3} {7E-}{{{\color{jlstring}7E-}}}{3} -{8E-}{{{\color{jlstring}8E-}}}{3} {9E-}{{{\color{jlstring}9E-}}}{3} -} - - -% special unicode characters -%\lstset{inputencoding=utf8} -%\DeclareUnicodeCharacter{0391}{A} -\lstset{extendedchars=true} -\lstset{literate= -% -% characters that appear in latin languages -% -{á}{{\'a}}{1} {é}{{\'e}}{1} {í}{{\'i}}{1} {ó}{{\'o}}{1} {ú}{{\'u}}{1} -{Á}{{\'A}}{1} {É}{{\'E}}{1} {Í}{{\'I}}{1} {Ó}{{\'O}}{1} {Ú}{{\'U}}{1} -{à}{{\`a}}{1} {è}{{\`e}}{1} {ì}{{\`i}}{1} {ò}{{\`o}}{1} {ù}{{\`u}}{1} -{À}{{\`A}}{1} {È}{{\'E}}{1} {Ì}{{\`I}}{1} {Ò}{{\`O}}{1} {Ù}{{\`U}}{1} -{ä}{{\"a}}{1} {ë}{{\"e}}{1} {ï}{{\"i}}{1} {ö}{{\"o}}{1} {ü}{{\"u}}{1} -{Ä}{{\"A}}{1} {Ë}{{\"E}}{1} {Ï}{{\"I}}{1} {Ö}{{\"O}}{1} {Ü}{{\"U}}{1} -{â}{{\^a}}{1} {ê}{{\^e}}{1} {î}{{\^i}}{1} {ô}{{\^o}}{1} {û}{{\^u}}{1} -{Â}{{\^A}}{1} {Ê}{{\^E}}{1} {Î}{{\^I}}{1} {Ô}{{\^O}}{1} {Û}{{\^U}}{1} -{œ}{{\oe}}{1} {Œ}{{\OE}}{1} {æ}{{\ae}}{1} {Æ}{{\AE}}{1} {ß}{{\ss}}{1} -{ű}{{\H{u}}}{1} {Ű}{{\H{U}}}{1} {ő}{{\H{o}}}{1} {Ő}{{\H{O}}}{1} -{ç}{{\c c}}{1} {Ç}{{\c C}}{1} {ø}{{\o}}{1} {å}{{\r a}}{1} {Å}{{\r A}}{1} -{€}{{\euro}}{1} {£}{{\pounds}}{1} {«}{{\guillemotleft}}{1} -{»}{{\guillemotright}}{1} {ñ}{{\~n}}{1} {Ñ}{{\~N}}1 {¿}{{?`}}{1} -% -% greek capital letters -% -{Α}{{\ucc{A}}}{1} {Β}{{\ucc{B}}}{1} {Γ}{{\ucc{$\Gamma$}}}{1} -{Δ}{{\ucc{$\Delta$}}}{1} {Ε}{{\ucc{E}}}{1} {Ζ}{{\ucc{Z}}}{1} -{Η}{{\ucc{H}}}{1} {Θ}{{\ucc{$\Theta$}}}{1} {Ι}{{\ucc{I}}}{1} -{Κ}{{\ucc{K}}}{1} {Λ}{{\ucc{$\Lambda$}}}{1} {Μ}{{\ucc{M}}}{1} -{Ν}{{\ucc{N}}}{1} {Ξ}{{\ucc{$\Xi$}}}{1} {Ο}{{\ucc{O}}}{1} -{Π}{{\ucc{$\Pi$}}}{1} {Ρ}{{\ucc{P}}}{1} {Σ}{{\ucc{$\Sigma$}}}{1} -{Τ}{{\ucc{T}}}{1} {Υ}{{\ucc{$\Upsilon$}}}{1} {Φ}{{\ucc{$\Phi$}}}{1} -{Χ}{{\ucc{X}}}{1} {Ψ}{{\ucc{$\Psi$}}}{1} {Ω}{{\ucc{$\Omega$}}}{1} -% -% mircro sign + latin small letter open e -% -{µ}{{\ucc{$\mu$}}}{1} {ɛ}{{\ucc{$\varepsilon$}}}{1} -% -% greek small letters -% -{α}{{\ucc{$\alpha$}}}{1} {β}{{\ucc{$\beta$}}}{1} {γ}{{\ucclit{$\gamma$}}}{1} -{δ}{{\ucc{$\delta$}}}{1} {ε}{{\ucc{$\varepsilon$}}}{1} -{ϵ}{{\ucc{$\epsilon$}}}{1} {ζ}{{\ucc{$\zeta$}}}{1} {η}{{\ucc{$\eta$}}}{1} -{θ}{{\ucc{$\theta$}}}{1} {ϑ}{{\ucc{$\vartheta$}}}{1} {ι}{{\ucc{$\iota$}}}{1} -{κ}{{\ucc{$\kappa$}}}{1} {ϰ}{{\ucc{$\varkappa$}}}{1} {λ}{{\ucc{$\lambda$}}}{1} -{μ}{{\ucc{$\mu$}}}{1} {ν}{{\ucc{$\nu$}}}{1} {ξ}{{\ucc{$\xi$}}}{1} -{ο}{{\ucc{o}}}{1} {π}{{\ucclit{$\pi$}}}{1} {ϖ}{{\ucc{$\varpi$}}}{1} -{ρ}{{\ucc{$\rho$}}}{1} {ϱ}{{\ucc{$\varrho$}}}{1} {σ}{{\ucc{$\sigma$}}}{1} -{ς}{{\ucc{$\varsigma$}}}{1} {τ}{{\ucc{$\tau$}}}{1} {υ}{{\ucc{$\upsilon$}}}{1} -{φ}{{\ucclit{$\phi$}}}{1} {ϕ}{{\ucc{$\varphi$}}}{1} {χ}{{\ucc{$\chi$}}}{1} -{ψ}{{\ucc{$\psi$}}}{1} {ω}{{\ucc{$\omega$}}}{1} -% -% superscripts -% -{⁽}{{\ucc{${\scriptstyle {}^{(}}$}}}{1} {⁾}{{\ucc{${\scriptstyle {}^{)}}$}}}{1} -{⁺}{{\ucc{${\scriptstyle {}^{+}}$}}}{1} {⁻}{{\ucc{${\scriptstyle {}^{-}}$}}}{1} -{⁰}{{\ucc{${\scriptstyle {}^{0}}$}}}{1} {¹}{{\ucc{${\scriptstyle {}^{1}}$}}}{1} -{²}{{\ucc{${\scriptstyle {}^{2}}$}}}{1} {³}{{\ucc{${\scriptstyle {}^{3}}$}}}{1} -{⁴}{{\ucc{${\scriptstyle {}^{4}}$}}}{1} {⁵}{{\ucc{${\scriptstyle {}^{5}}$}}}{1} -{⁶}{{\ucc{${\scriptstyle {}^{6}}$}}}{1} {⁷}{{\ucc{${\scriptstyle {}^{7}}$}}}{1} -{⁸}{{\ucc{${\scriptstyle {}^{8}}$}}}{1} {⁹}{{\ucc{${\scriptstyle {}^{9}}$}}}{1} -{⁼}{{\ucc{${\scriptstyle {}^{=}}$}}}{1} {ᴬ}{{\ucc{${\scriptstyle {}^{A}}$}}}{1} -{ᴮ}{{\ucc{${\scriptstyle {}^{B}}$}}}{1} {ᴰ}{{\ucc{${\scriptstyle {}^{D}}$}}}{1} -{ᴱ}{{\ucc{${\scriptstyle {}^{E}}$}}}{1} {ᴳ}{{\ucc{${\scriptstyle {}^{G}}$}}}{1} -{ᴴ}{{\ucc{${\scriptstyle {}^{H}}$}}}{1} {ᴵ}{{\ucc{${\scriptstyle {}^{I}}$}}}{1} -{ᴶ}{{\ucc{${\scriptstyle {}^{J}}$}}}{1} {ᴷ}{{\ucc{${\scriptstyle {}^{K}}$}}}{1} -{ᴸ}{{\ucc{${\scriptstyle {}^{L}}$}}}{1} {ᴹ}{{\ucc{${\scriptstyle {}^{M}}$}}}{1} -{ᴺ}{{\ucc{${\scriptstyle {}^{N}}$}}}{1} {ᴼ}{{\ucc{${\scriptstyle {}^{O}}$}}}{1} -{ᴾ}{{\ucc{${\scriptstyle {}^{P}}$}}}{1} {ᴿ}{{\ucc{${\scriptstyle {}^{R}}$}}}{1} -{ᵀ}{{\ucc{${\scriptstyle {}^{T}}$}}}{1} {ᵁ}{{\ucc{${\scriptstyle {}^{U}}$}}}{1} -{ⱽ}{{\ucc{${\scriptstyle {}^{V}}$}}}{1} {ᵂ}{{\ucc{${\scriptstyle {}^{W}}$}}}{1} -{ᵃ}{{\ucc{${\scriptstyle {}^{a}}$}}}{1} {ᵇ}{{\ucc{${\scriptstyle {}^{b}}$}}}{1} -{ᶜ}{{\ucc{${\scriptstyle {}^{c}}$}}}{1} {ᵈ}{{\ucc{${\scriptstyle {}^{d}}$}}}{1} -{ᵉ}{{\ucc{${\scriptstyle {}^{e}}$}}}{1} {ᶠ}{{\ucc{${\scriptstyle {}^{f}}$}}}{1} -{ᵍ}{{\ucc{${\scriptstyle {}^{g}}$}}}{1} {ʰ}{{\ucc{${\scriptstyle {}^{h}}$}}}{1} -{ⁱ}{{\ucc{${\scriptstyle {}^{i}}$}}}{1} {ʲ}{{\ucc{${\scriptstyle {}^{j}}$}}}{1} -{ᵏ}{{\ucc{${\scriptstyle {}^{k}}$}}}{1} {ˡ}{{\ucc{${\scriptstyle {}^{l}}$}}}{1} -{ᵐ}{{\ucc{${\scriptstyle {}^{m}}$}}}{1} {ⁿ}{{\ucc{${\scriptstyle {}^{n}}$}}}{1} -{ᵒ}{{\ucc{${\scriptstyle {}^{o}}$}}}{1} {ᵖ}{{\ucc{${\scriptstyle {}^{p}}$}}}{1} -{ʳ}{{\ucc{${\scriptstyle {}^{r}}$}}}{1} {ˢ}{{\ucc{${\scriptstyle {}^{s}}$}}}{1} -{ᵗ}{{\ucc{${\scriptstyle {}^{t}}$}}}{1} {ᵘ}{{\ucc{${\scriptstyle {}^{u}}$}}}{1} -{ᵛ}{{\ucc{${\scriptstyle {}^{v}}$}}}{1} {ʷ}{{\ucc{${\scriptstyle {}^{w}}$}}}{1} -{ˣ}{{\ucc{${\scriptstyle {}^{x}}$}}}{1} {ʸ}{{\ucc{${\scriptstyle {}^{y}}$}}}{1} -{ᶻ}{{\ucc{${\scriptstyle {}^{z}}$}}}{1} -{ᵅ}{{\ucc{${\scriptstyle {}^{\alpha}}$}}}{1} -{ᵝ}{{\ucc{${\scriptstyle {}^{\beta}}$}}}{1} -{ᵞ}{{\ucc{${\scriptstyle {}^{\gamma}}$}}}{1} -{ᵟ}{{\ucc{${\scriptstyle {}^{\delta}}$}}}{1} -{ᵋ}{{\ucc{${\scriptstyle {}^{\varepsilon}}$}}}{1} -{ᶿ}{{\ucc{${\scriptstyle {}^{\theta}}$}}}{1} -{ᶥ}{{\ucc{${\scriptstyle {}^{\iota}}$}}}{1} -{ᶲ}{{\ucc{${\scriptstyle {}^{\phi}}$}}}{1} -{ᵡ}{{\ucc{${\scriptstyle {}^{\chi}}$}}}{1} -{ᵠ}{{\ucc{${\scriptstyle {}^{\psi}}$}}}{1} -% -% subscripts -% -{₍}{{\ucc{${\scriptstyle {}_{(}}$}}}{1} {₎}{{\ucc{${\scriptstyle {}_{)}}$}}}{1} -{₊}{{\ucc{${\scriptstyle {}_{+}}$}}}{1} {₋}{{\ucc{${\scriptstyle {}_{-}}$}}}{1} -{₀}{{\ucc{${\scriptstyle {}_{0}}$}}}{1} {₁}{{\ucc{${\scriptstyle {}_{1}}$}}}{1} -{₂}{{\ucc{${\scriptstyle {}_{2}}$}}}{1} {₃}{{\ucc{${\scriptstyle {}_{3}}$}}}{1} -{₄}{{\ucc{${\scriptstyle {}_{4}}$}}}{1} {₅}{{\ucc{${\scriptstyle {}_{5}}$}}}{1} -{₆}{{\ucc{${\scriptstyle {}_{6}}$}}}{1} {₇}{{\ucc{${\scriptstyle {}_{7}}$}}}{1} -{₈}{{\ucc{${\scriptstyle {}_{8}}$}}}{1} {₉}{{\ucc{${\scriptstyle {}_{9}}$}}}{1} -{₌}{{\ucc{${\scriptstyle {}_{=}}$}}}{1} {ₐ}{{\ucc{${\scriptstyle {}_{a}}$}}}{1} -{ₑ}{{\ucc{${\scriptstyle {}_{e}}$}}}{1} {ₕ}{{\ucc{${\scriptstyle {}_{h}}$}}}{1} -{ᵢ}{{\ucc{${\scriptstyle {}_{i}}$}}}{1} {ⱼ}{{\ucc{${\scriptstyle {}_{j}}$}}}{1} -{ₖ}{{\ucc{${\scriptstyle {}_{k}}$}}}{1} {ₗ}{{\ucc{${\scriptstyle {}_{l}}$}}}{1} -{ₘ}{{\ucc{${\scriptstyle {}_{m}}$}}}{1} {ₙ}{{\ucc{${\scriptstyle {}_{n}}$}}}{1} -{ₒ}{{\ucc{${\scriptstyle {}_{o}}$}}}{1} {ₚ}{{\ucc{${\scriptstyle {}_{p}}$}}}{1} -{ᵣ}{{\ucc{${\scriptstyle {}_{r}}$}}}{1} {ₛ}{{\ucc{${\scriptstyle {}_{s}}$}}}{1} -{ₜ}{{\ucc{${\scriptstyle {}_{t}}$}}}{1} {ᵤ}{{\ucc{${\scriptstyle {}_{u}}$}}}{1} -{ᵥ}{{\ucc{${\scriptstyle {}_{v}}$}}}{1} {ₓ}{{\ucc{${\scriptstyle {}_{x}}$}}}{1} -{ᵦ}{{\ucc{${\scriptstyle {}_{\beta}}$}}}{1} -{ᵧ}{{\ucc{${\scriptstyle {}_{\gamma}}$}}}{1} -{ᵨ}{{\ucc{${\scriptstyle {}_{\rho}}$}}}{1} -{ᵪ}{{\ucc{${\scriptstyle {}_{\chi}}$}}}{1} -{ᵩ}{{\ucc{${\scriptstyle {}_{\psi}}$}}}{1} -% -} - - - - - -% basic font -\makeatletter -\def\lstbasicfont{% - \color{jlstring}% - \ttfamily% - \lst@ifdisplaystyle\scriptsize\fi% -} -\makeatother - -% general style of the code block -\lstset{basicstyle={\lstbasicfont}} -\lstset{showstringspaces=false} -\lstset{upquote=true} -\lstset{tabsize=4} -\lstset{aboveskip={1.5\baselineskip},belowskip={1.5\baselineskip}} - -% creating the code box -\lstset{backgroundcolor=\color{jlbackground}, rulecolor=\color{jlrule}} -\lstset{frame=single, frameround=tttt} -\lstset{columns=fixed} -\newlength{\bfem} -\settowidth{\bfem}{\lstbasicfont{m}} -\newlength{\xmrgn} -\setlength{\xmrgn}{(\textwidth - 80\bfem)*\real{0.5}} -\lstset{basewidth=\bfem} - -% activating the julia style -\lstset{language=julia} diff --git a/paper/journal_dat.tex b/paper/journal_dat.tex deleted file mode 100644 index a925030..0000000 --- a/paper/journal_dat.tex +++ /dev/null @@ -1,6 +0,0 @@ -% **************GENERATED FILE, DO NOT EDIT************** - -\def\@journalName{Proceedings of JuliaCon} -\def\@volume{1} -\def\@issue{1} -\def\@year{2021} diff --git a/paper/juliacon.bst b/paper/juliacon.bst deleted file mode 100644 index aaf1930..0000000 --- a/paper/juliacon.bst +++ /dev/null @@ -1,1189 +0,0 @@ -% BibTeX standard bibliography style `plain' - % version 0.99a for BibTeX versions 0.99a or later, LaTeX version 2.09. - % Copyright (C) 1985, all rights reserved. - % Copying of this file is authorized only if either - % (1) you make absolutely no changes to your copy, including name, or - % (2) if you do make changes, you name it something other than - % btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. - % This restriction helps ensure that all standard styles are identical. - % The file btxbst.doc has the documentation for this style. - -ENTRY - { address - author - booktitle - chapter - edition - editor - eprint - eprinttype - eprintclass - howpublished - institution - journal - key - month - note - number - organization - pages - publisher - school - series - title - type - volume - year - doi - } - {} - { label } - -INTEGERS { output.state before.all mid.sentence after.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.sentence := - #3 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "" write$ - } - { output.state before.all = - 'write$ - { add.period$ " " * write$ } - if$ - } - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -FUNCTION {output.bibitem} -{ newline$ - "\bibitem{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} -{ add.period$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ - } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.sentence.checka} -{ empty$ - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {new.sentence.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " et~al." * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {format.authors} -{ author empty$ - { "" } - { author format.names } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor format.names - editor num.names$ #1 > - { ", editors" * } - { ", editor" * } - if$ - } - if$ -} - -FUNCTION {format.eprint} -{ eprint empty$ - { "" } - { eprinttype empty$ - { eprintclass empty$ - { eprint } - { eprint " [" * eprintclass * "]" * } - if$ - } - { eprinttype "arxiv" = - { eprintclass empty$ - { eprinttype ":" * "\href{http://arxiv.org/abs/" * eprint * "}{" * eprint * "}" * } - { eprinttype ":" * "\href{http://arxiv.org/abs/" * eprint * "}{" * eprint * " [" * eprintclass * "]" * "}" * } - if$ - } - { eprintclass empty$ - { eprinttype ":" * eprint * } - { eprinttype ":" * eprint * " [" * eprintclass * "]" *} - if$ - } - if$ - } - if$ - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { title "t" change.case$ } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } - if$ - } - { month empty$ - 'year - { month " " * year * } - if$ - } - if$ -} - -FUNCTION {format.btitle} -{ title emphasize -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "volume" volume tie.or.space.connect - series empty$ - 'skip$ - { " of " * series emphasize * } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { output.state mid.sentence = - { "number" } - { "Number" } - if$ - number tie.or.space.connect - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { output.state mid.sentence = - { edition "l" change.case$ " edition" * } - { edition "t" change.case$ " edition" * } - if$ - } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pages" pages n.dashify tie.or.space.connect } - { "page" pages tie.or.space.connect } - if$ - } - if$ -} - -FUNCTION {format.vol.num.pages} -{ volume field.or.null - number empty$ - 'skip$ - { "(" number * ")" * * - volume empty$ - { "there's a number but no volume in " cite$ * warning$ } - 'skip$ - if$ - } - if$ - pages empty$ - 'skip$ - { duplicate$ empty$ - { pop$ format.pages } - { ":" * pages n.dashify * } - if$ - } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ - { "chapter" } - { type "l" change.case$ } - if$ - chapter tie.or.space.connect - pages empty$ - 'skip$ - { ", " * format.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { editor empty$ - { "In " booktitle emphasize * } - { "In " format.editors * ", " * booktitle emphasize * } - if$ - } - if$ -} - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and - key empty$ not and - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "t" change.case$ - } - if$ -} - -FUNCTION {format.tr.number} -{ type empty$ - { "Technical Report" } - 'type - if$ - number empty$ - { "t" change.case$ } - { number tie.or.space.connect } - if$ -} - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "In {\em " journal * "\/}" * } - if$ - } - { "In " key * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.crossref.editor} -{ editor #1 "{vv~}{ll}" format.name$ - editor num.names$ duplicate$ - #2 > - { pop$ " et~al." * } - { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " et~al." * } - { " and " * editor #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "In " - } - { "Volume" volume tie.or.space.connect - " of " * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "{\em " * series * "\/}" * } - if$ - } - { key * } - if$ - } - { format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "In {\em " booktitle * "\/}" * } - if$ - } - { "In " key * } - if$ - } - { "In " format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -% based on -% https://tex.stackexchange.com/a/127819/245 -FUNCTION {output.doi} -{ - doi empty$ - { skip$ } - { "\href{http://dx.doi.org/" doi * "}{doi:" * doi * "}" * output } - if$ -} - - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { journal emphasize "journal" output.check - format.vol.num.pages output - format.date "year" output.check - } - { format.article.crossref output.nonnull - format.pages output - } - if$ - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - output.doi - new.block - note output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - format.authors output - new.block - format.title "title" output.check - howpublished address new.block.checkb - howpublished output - address output - format.date output - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.chapter.pages "chapter and pages" output.check - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { format.chapter.pages "chapter and pages" output.check - new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.chapter.pages output - new.sentence - publisher "publisher" output.check - address output - format.edition output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull - format.chapter.pages output - } - if$ - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.pages output - address empty$ - { organization publisher new.sentence.checkb - organization output - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - organization output - publisher output - } - if$ - } - { format.incoll.inproc.crossref output.nonnull - format.pages output - } - if$ - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization empty$ - 'skip$ - { organization output.nonnull - address output - } - if$ - } - { format.authors output.nonnull } - if$ - new.block - format.btitle "title" output.check - author empty$ - { organization empty$ - { address new.block.checka - address output - } - 'skip$ - if$ - } - { organization address new.block.checkb - organization output - address output - } - if$ - format.edition output - format.date output - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - format.authors output - title howpublished new.block.checkb - format.title output - howpublished new.block.checka - howpublished output - format.date output - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry - empty.misc.check -} - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.btitle "title" output.check - new.block - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - editor empty$ - { organization output } - { format.editors output.nonnull } - if$ - new.block - format.btitle "title" output.check - format.bvolume output - format.number.series output - address empty$ - { editor empty$ - { publisher new.sentence.checka } - { organization publisher new.sentence.checkb - organization output - } - if$ - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - editor empty$ - 'skip$ - { organization output } - if$ - publisher output - } - if$ - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - format.tr.number output.nonnull - institution "institution" output.check - address output - format.date "year" output.check - new.block - output.doi - new.block - format.eprint output - new.block - note output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - output.doi - new.block - format.eprint output - new.block - note "note" output.check - format.date output - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"January"} - -MACRO {feb} {"February"} - -MACRO {mar} {"March"} - -MACRO {apr} {"April"} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"August"} - -MACRO {sep} {"September"} - -MACRO {oct} {"October"} - -MACRO {nov} {"November"} - -MACRO {dec} {"December"} - -MACRO {acmcs} {"ACM Computing Surveys"} - -MACRO {acta} {"Acta Informatica"} - -MACRO {cacm} {"Communications of the ACM"} - -MACRO {ibmjrd} {"IBM Journal of Research and Development"} - -MACRO {ibmsj} {"IBM Systems Journal"} - -MACRO {ieeese} {"IEEE Transactions on Software Engineering"} - -MACRO {ieeetc} {"IEEE Transactions on Computers"} - -MACRO {ieeetcad} - {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} - -MACRO {ipl} {"Information Processing Letters"} - -MACRO {jacm} {"Journal of the ACM"} - -MACRO {jcss} {"Journal of Computer and System Sciences"} - -MACRO {scp} {"Science of Computer Programming"} - -MACRO {sicomp} {"SIAM Journal on Computing"} - -MACRO {tocs} {"ACM Transactions on Computer Systems"} - -MACRO {tods} {"ACM Transactions on Database Systems"} - -MACRO {tog} {"ACM Transactions on Graphics"} - -MACRO {toms} {"ACM Transactions on Mathematical Software"} - -MACRO {toois} {"ACM Transactions on Office Information Systems"} - -MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} - -MACRO {tcs} {"Theoretical Computer Science"} - -READ - -FUNCTION {sortify} -{ purify$ - "l" change.case$ -} - -INTEGERS { len } - -FUNCTION {chop.word} -{ 's := - 'len := - s #1 len substring$ = - { s len #1 + global.max$ substring$ } - 's - if$ -} - -FUNCTION {sort.format.names} -{ 's := - #1 'nameptr := - "" - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { nameptr #1 > - { " " * } - 'skip$ - if$ - s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't := - nameptr numnames = t "others" = and - { "et al" * } - { t sortify * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {sort.format.title} -{ 't := - "A " #2 - "An " #3 - "The " #4 t chop.word - chop.word - chop.word - sortify - #1 global.max$ substring$ -} - -FUNCTION {author.sort} -{ author empty$ - { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.editor.sort} -{ author empty$ - { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.organization.sort} -{ author empty$ - { organization empty$ - { key empty$ - { "to sort, need author, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {editor.organization.sort} -{ editor empty$ - { organization empty$ - { key empty$ - { "to sort, need editor, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { editor sort.format.names } - if$ -} - -FUNCTION {presort} -{ type$ "book" = - type$ "inbook" = - or - 'author.editor.sort - { type$ "proceedings" = - 'editor.organization.sort - { type$ "manual" = - 'author.organization.sort - 'author.sort - if$ - } - if$ - } - if$ - " " - * - year field.or.null sortify - * - " " - * - title field.or.null - sort.format.title - * - #1 entry.max$ substring$ - 'sort.key$ := -} - -ITERATE {presort} - -SORT - -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #1 'number.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ number.label int.to.str$ 'label := - number.label #1 + 'number.label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -FUNCTION {begin.bib} -{ preamble$ empty$ - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{" longest.label * "}" * write$ newline$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/paper/juliacon.cls b/paper/juliacon.cls deleted file mode 100644 index e2c156f..0000000 --- a/paper/juliacon.cls +++ /dev/null @@ -1,944 +0,0 @@ -%% juliacon.cls - version 1.0 - -%% Inspired by the template from the International Journal of Computer Applications (IJCA) - -\usepackage[scaled=0.92]{helvet} -\def\fileversion{v1.0} -\def\filedate{2019 04 07} -% -\NeedsTeXFormat{LaTeX2e} -\ProvidesClass{juliacon} -\RequirePackage{latexsym} -\RequirePackage{url} - -\usepackage[utf8]{inputenc} -\usepackage[T1]{fontenc} - -\newif\ifmanuscript -\@twosidetrue\@mparswitchtrue -% -\newdimen\trimheight -\newdimen\trimwidth -\newdimen\typeheight -\newdimen\typewidth -\newdimen\normaltextheight -\newdimen\blindfoliodrop -\newbox\tempbox -%% - -\input{journal_dat} - -% -\frenchspacing % oh lala bravo quelle belle idée -\DeclareOption{manuscript}{\manuscripttrue} -\DeclareOption{letterpaper} - {\setlength\paperheight {11.69in}% - \setlength\paperwidth {8.27in}% - \def\special@paper{8.5in,11in} - \special{papersize=8.5in,11in}} - -\DeclareOption{openbib}{% - \AtEndOfPackage{% - \renewcommand\@openbib@code{% - \advance\leftmargin\bibindent - \itemindent -\bibindent - \listparindent \itemindent - \parsep \z@ - }% - \renewcommand\newblock{\par}}% -} -% -\ExecuteOptions{letterpaper} -\ProcessOptions -% -\newcommand\refname{References} -\newcommand{\ignoretwo}[2]{} -\newcommand{\yearTwoDigits}{\expandafter\ignoretwo\the\year} -\def\@setref#1#2#3{% - \ifx#1\relax - \number 0\relax - \protect\G@refundefinedtrue - \nfss@text{\reset@font\bfseries ??}% - \@latex@warning{Reference `#3' on page \thepage \space undefined}% - \else - \expandafter#2#1\null - \fi} -% -% -\lineskip 1pt \normallineskip 1pt -\ifmanuscript -\def\baselinestretch{2} -\else -\def\baselinestretch{1} -\fi -\def\@ixpt{9} -\renewcommand\normalsize{% - \@setfontsize\normalsize\@ixpt{10pt} - \abovedisplayskip 6pt plus2pt minus1pt\belowdisplayskip \abovedisplayskip - \abovedisplayshortskip 6pt plus0pt minus 3pt - \belowdisplayshortskip 6pt plus0pt minus3pt\let\@listi\@listI} - -\newcommand\small{% - \@setfontsize\small\@ixpt{11pt}% - \abovedisplayskip 5pt plus 2pt minus 1pt\belowdisplayskip \abovedisplayskip - \abovedisplayshortskip 5pt plus0pt minus2pt\belowdisplayshortskip 5pt plus0pt - minus 2pt - \def\@listi{\leftmargin\leftmargini \topsep 5pt plus 2pt minus 1pt\parsep 0pt - plus .7pt - \itemsep 1.6pt plus .8pt}} -\newcommand\footnotesize{% -% \@setfontsize\footnotesize\@viiipt{10pt} - \@setsize\footnotesize{10pt}\viiipt\@viiipt - \abovedisplayskip 4pt plus 1pt minus 0pt\belowdisplayskip \abovedisplayskip - \abovedisplayshortskip 4pt plus 0pt minus 1pt\belowdisplayshortskip 4pt plus - 0pt minus 1pt - \def\@listi{\leftmargin\leftmargini \topsep 4pt plus 1pt minus - 0pt\parsep 0pt plus .5pt - \itemsep 1pt plus .7pt}} - -\newcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt} -\newcommand\tiny{\@setfontsize\tiny\@vpt\@vipt} -\newcommand\large{\@setfontsize\large\@xiipt{14}} -\newcommand\Large{\@setfontsize\Large\@xivpt{18}} -\newcommand\LARGE{\@setfontsize\LARGE\@xviipt{20}} -\newcommand\huge{\@setfontsize\huge\@xxpt{25}} -\newcommand\Huge{\@setfontsize\Huge\@xxvpt{30}} -% -\normalsize -% -\newdimen\tempdimen -% -\setlength\trimheight{11in} -\setlength\trimwidth{8.5in} -% -\typeheight52.5pc -\typewidth42pc -\textheight52.5pc -\textwidth42pc -\advance\textheight-3pt -\newdimen\normaltextheight -\setlength\normaltextheight{\textheight} -\oddsidemargin4.5pc -\evensidemargin4.5pc -\topmargin20pt %.25in -\headheight 6pt% -\headsep 29.2pt% -\topskip6pt% -\footskip 100pt -% -\marginparwidth 0.5in -\marginparsep .125in -\columnsep24pt -\columnseprule 0pt -% -\def\titlefont{\huge\selectfont\centering\mathversion{bold}} -\def\authorfont{\fontfamily{phv}\fontsize{10}{12}\selectfont\rightskip0pt plus1fill} %\mathversion{sfnormal} -\def\rhfont{\fontfamily{phv}\fontsize{9}{10}\selectfont\mathversion{sfnormal}} - -\def\sectionfont{\fontfamily{ptm}\fontsize{9}{12}\capsshape\selectfont\raggedright} %\mathversion{rmnormal} -\def\subsectionfont{\fontfamily{ptm}\fontsize{9}{12}\selectfont} %\mathversion{rmnormal} -\def\figcaptionfont{\fontsize{8}{10}\selectfont\mathversion{normal}}% -\def\subcaptionfont{\fontsize{8}{10}\selectfont\mathversion{normal}}% -\def\subcaption#1{{\centering\subcaptionfont#1\par}} -% -\def\tablefont{\fontsize{8}{10}\selectfont}% -\def\tablecaptionfont{\fontsize{9}{11}\selectfont\centering}% -\def\tablenumfont{\fontsize{9}{11}\selectfont}% -\def\tabnotefont{\fontsize{7}{9}\selectfont} -% -\def\encodingdefault{OT1}% -\fontencoding{OT1}% -% -\DeclareFontShape{OMS}{cmsy}{m}{n}{<-> cmsy10 }{} -\DeclareFontShape{OMS}{cmsy}{b}{n}{<-> cmbsy10 }{} -\def\cal{\mathcal} -% -\def\boldmath{\mathversion{bold}} -\def\bm#1{\mathchoice - {\mbox{\boldmath$\displaystyle#1$}}% - {\mbox{\boldmath$#1$}}% - {\mbox{\boldmath$\scriptstyle#1$}}% - {\mbox{\boldmath$\scriptscriptstyle#1$}}} -% -\footnotesep 7pt -\skip\footins 15pt plus 4pt minus 3pt -\floatsep 12pt plus 2pt minus 2pt -\textfloatsep \floatsep -\intextsep 1pc plus 1pc -\dblfloatsep 12pt plus 2pt minus 2pt -\dbltextfloatsep 20pt plus 2pt minus 4pt -\@fptop 0pt plus 1fil \@fpsep 1pc plus 2fil \@fpbot 0pt plus 1fil -\@dblfptop 0pt plus 1fil \@dblfpsep 8pt plus 2fil \@dblfpbot 0pt plus 1fil -\marginparpush 6pt -\parskip 0pt \parindent 0pt \partopsep 0pt % plus .1pt FBU -\@lowpenalty 51 \@medpenalty 151 \@highpenalty 301 -\@beginparpenalty -\@lowpenalty \@endparpenalty -\@lowpenalty \@itempenalty --\@lowpenalty -% -\def\part{\@ucheadtrue - \@startsection{part}{9}{\z@}{-10pt plus -4pt minus - -2pt}{4pt}{\reset@font\normalsize\rmfamily}} -\def\section{\@ucheadtrue - \@startsection{section}{1}{\z@}{-10pt plus -4pt minus - -2pt}{6pt}{\reset@font\fontsize{10}{12}\raggedright\rmfamily\bfseries}} -\def\subsection{\@ucheadfalse - \@startsection{subsection}{2}{\z@}{-8pt plus -2pt minus - -1pt}{6pt}{\reset@font\fontsize{10}{12}\raggedright\rmfamily\bfseries}} -\def\subsubsection{\@ucheadfalse - \@startsection{subsubsection}{3}{\parindent}{6pt plus -1pt}{-5pt}{\reset@font\fontsize{9}{10}\itshape}} -\def\paragraph{\@ucheadfalse - \@startsection{paragraph}{3}{\parindent}{6pt plus -1pt}{-5pt}{\reset@font\fontsize{10}{12}\itshape}} -%% -\renewcommand{\@seccntformat}[1]{\textup{\csname the#1\endcsname}} -\gdef\@period{.} -\def\@trivlist{\@topsepadd\topsep -\if@noskipsec \gdef\@period{}\leavevmode\gdef\@period{.}\fi - \ifvmode \advance\@topsepadd\partopsep \else \unskip\par\fi - \if@inlabel \@noparitemtrue \@noparlisttrue - \else \@noparlistfalse \@topsep\@topsepadd \fi - \advance\@topsep \parskip - \leftskip\z@\rightskip\@rightskip \parfillskip\@flushglue - \@setpar{\if@newlist\else{\@@par}\fi} \global\@newlisttrue -\@outerparskip\parskip} -% -\def\@startsection#1#2#3#4#5#6{% - \if@noskipsec \leavevmode \fi - \par - \@tempskipa #4\relax - \@afterindenttrue - \ifdim \@tempskipa <\z@ - \@tempskipa -\@tempskipa \@afterindentfalse - \fi - \if@nobreak - \everypar{}% - \ifnum#2=2 - \vskip-2pt - \fi - \else - \addpenalty\@secpenalty\addvspace\@tempskipa - \fi - \@ifstar - {\@ssect{#3}{#4}{#5}{#6}}% - {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}} -% -\def\@sect#1#2#3#4#5#6[#7]#8{% - \ifnum #2>\c@secnumdepth - \let\@svsec\@empty - \else - \refstepcounter{#1}% - \if@uchead% - \protected@edef\@svsec{\@seccntformat{#1}.\quad\relax}% - \else% - \protected@edef\@svsec{\@seccntformat{#1}\quad\relax}% - \fi% - \fi - \@tempskipa #5\relax - \ifdim \@tempskipa>\z@ - \begingroup - #6{% - \@hangfrom{\hskip #3\relax\@svsec}% - \interlinepenalty \@M #8 \@@par}% - \endgroup - \csname #1mark\endcsname{#7}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - #7}% - \else - \def\@svsechd{% - #6{\hskip #3\relax - \@svsec \if@uchead\Makeuppercase{#8}\else#8\fi}% - \csname #1mark\endcsname{#7}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - #7}}% - \fi - \@xsect{#5}} - -\def\@xsect#1{\@tempskipa #1\relax - \ifdim \@tempskipa>\z@ - \par \nobreak - \vskip \@tempskipa - \@afterheading - \else \global\@nobreakfalse \global\@noskipsectrue - \everypar{\if@noskipsec \global\@noskipsecfalse - \clubpenalty\@M \hskip -\parindent - \begingroup \@svsechd\@period \endgroup \unskip - \hskip -#1 - \else \clubpenalty \@clubpenalty - \everypar{}\fi}\fi\ignorespaces} -\newif\if@uchead\@ucheadfalse -% -\setcounter{secnumdepth}{3} -\newcounter{secnumbookdepth} -\setcounter{secnumbookdepth}{3} -\newfont{\apbf}{cmbx9} -\def\appendix{\par - \setcounter{section}{0} - \setcounter{subsection}{0} - \section*{APPENDIX}\vskip10pt - \def\thesection{\Alph{section}} - \def\theHsection{\Alph{section}}} -% -\labelsep 4pt -\settowidth{\leftmargini}{(9)} \addtolength\leftmargini\labelsep -\settowidth{\leftmarginii}{(b)} \addtolength\leftmarginii\labelsep -\leftmarginiii \leftmarginii -\leftmarginiv \leftmarginii -\leftmarginv \leftmarginii -\leftmarginvi \leftmarginii -\leftmargin\leftmargini -\labelwidth\leftmargini\advance\labelwidth-\labelsep -\def\@listI{\leftmargin\leftmargini \parsep 0pt plus 1pt\topsep 6pt plus 2pt -minus 2pt\itemsep 2pt plus 1pt minus .5pt} -\let\@listi\@listI -\@listi -\def\@listii{\leftmargin\leftmarginii - \labelwidth\leftmarginii\advance\labelwidth-\labelsep - \topsep 0pt plus 1pt - \parsep 0pt plus .5pt - \itemsep \parsep} -\def\@listiii{\leftmargin\leftmarginiii - \labelwidth\leftmarginiii\advance\labelwidth-\labelsep - \topsep 0pt plus 1pt - \parsep 0pt plus .5pt - \itemsep \parsep} -\def\@listiv{\leftmargin\leftmarginiv - \labelwidth\leftmarginiv\advance\labelwidth-\labelsep} -\def\@listv{\leftmargin\leftmarginv - \labelwidth\leftmarginv\advance\labelwidth-\labelsep} -\def\@listvi{\leftmargin\leftmarginvi - \labelwidth\leftmarginvi\advance\labelwidth-\labelsep} -% -\def\enumerate{\ifnum \@enumdepth >3 \@toodeep\else - \advance\@enumdepth \@ne - \edef\@enumctr{enum\romannumeral\the\@enumdepth}\list - {\csname label\@enumctr\endcsname}{\usecounter - {\@enumctr}\def\makelabel##1{##1\hss}}\fi} -\def\longenum{\ifnum \@enumdepth >3 \@toodeep\else - \advance\@enumdepth \@ne - \edef\@enumctr{enum\romannumeral\the\@enumdepth}\list - {\csname label\@enumctr\endcsname}{\usecounter - {\@enumctr}\labelwidth\z@}\fi} -\let\endlongenum\endlist -\def\labelenumi{{\rm (}\arabic{enumi}\/{\rm )}} -\def\theenumi{\arabic{enumi}} -\def\labelenumii{{\rm (}\alph{enumii}\rm{)}} -\def\theenumii{\alph{enumii}} -\def\p@enumii{\theenumi} -\def\labelenumiii{\roman{enumiii}.} -\def\theenumiii{\roman{enumiii}} -\def\p@enumiii{\theenumi{\rm (}\theenumii{\rm )}} -\def\labelenumiv{\Alph{enumiv}.} -\def\theenumiv{\Alph{enumiv}} -\renewcommand\theenumiv{\@Alph\c@enumiv} -\def\p@enumiv{\p@enumiii\theenumiii} - -\def\p@enumiv{\p@enumiii\theenumiii} - -\renewcommand\p@enumii{\theenumi} -\renewcommand\p@enumiii{\theenumi(\theenumii)} -\renewcommand\p@enumiv{\p@enumiii\theenumiii} - -\def\itemize{\list{---\hskip -\labelsep}{\settowidth - {\leftmargin}{---}\labelwidth\leftmargin - \addtolength{\labelwidth}{-\labelsep}}} -\let\enditemize\endlist -\def\longitem{\list{---}{\labelwidth\z@ - \leftmargin\z@ \itemindent\parindent \advance\itemindent\labelsep}} -\let\endlongitem\endlist -\def\verse{\let\\=\@centercr - \list{}{\leftmargin 2pc - \itemindent -1.5em\listparindent \itemindent - \rightmargin\leftmargin\advance\leftmargin 1.5em}\item[]} -\let\endverse\endlist -\def\quotation{\list{}{\leftmargin 2pc \listparindent .5em - \itemindent\listparindent - \rightmargin\leftmargin \parsep 0pt plus 1pt}\item[]} -\let\endquotation=\endlist -\def\quote{\list{}{\leftmargin 2pc \rightmargin\leftmargin}\item[]} -\let\endquote=\endlist - -% -\newenvironment{unnumlist}{% - \list{}{% - \listparindent\parindent - \itemindent-1em - \leftmargin1em - \parsep0pt - \itemsep2pt - \partopsep0pt} - \def\makelable##1{##1}% -}{\endlist}% -% -\def\description{\list{}{\listparindent\parindent\labelwidth\z@ - \leftmargin\z@ \itemindent\parindent\advance\itemindent\labelsep - \def\makelabel##1{\it ##1}}} -\let\enddescription\endlist -% -\def\describe#1{\list{}{\listparindent\parindent\settowidth{\labelwidth}{#1}\leftmargin - \labelwidth\addtolength\leftmargin\labelsep\def\makelabel##1{##1\hfil}}} -\let\enddescribe\endlist -% -\def\program{\ifx\@currsize\normalsize\small \else \rm \fi\tabbing} -\let\endprogram\endtabbing -% -\newtheorem{theorem}{Theorem} -\newtheorem{strategy}{Strategy} -\newtheorem{property}{Property} -\newtheorem{proposition}{Proposition} -\newtheorem{lemma}[theorem]{Lemma} -\newtheorem{exam}{Example} -\newenvironment{example}{% -\italicenvfalse -\begin{exam}}{\end{exam}\italicenvtrue} -% -\newtheorem{defi}[theorem]{Definition} -\newenvironment{definition}{% -\italicenvfalse -\begin{defi}}{\end{defi}\italicenvtrue} -% -\def\@begintheorem#1#2{\trivlist \item[\hskip 10pt\hskip - \labelsep{\sc{#1}\hskip 5pt\relax #2.}] \itshape} -% -\def\@opargbegintheorem#1#2#3{\trivlist - \item[\hskip 10pt \hskip -\labelsep{\sc{#1}\savebox\@tempboxa{\sc{#3}}\ifdim - \wd\@tempboxa>\z@ \hskip 5pt\relax \sc{#2} \box\@tempboxa\fi.}] -\itshape} -% -\newif\if@qeded\global\@qededfalse -\def\proof{\global\@qededfalse\@ifnextchar[{\@xproof}{\@proof}} -\def\endproof{\if@qeded\else\qed\fi\endtrivlist} -\def\qed{\unskip\kern 10pt{\unitlength1pt\linethickness{.4pt}\framebox(5,5){}} -\global\@qededtrue} -\def\@proof{\trivlist \item[\hskip 10pt\hskip - \labelsep{\sc Proof.}]\ignorespaces} -\def\@xproof[#1]{\trivlist \item[\hskip 10pt\hskip - \labelsep{\sc Proof #1.}]\ignorespaces} -% -\def\newdef#1#2{\expandafter\@ifdefinable\csname #1\endcsname -{\@definecounter{#1}\expandafter\xdef\csname -the#1\endcsname{\@thmcounter{#1}}\global - \@namedef{#1}{\@defthm{#1}{#2}}\global - \@namedef{end#1}{\@endtheorem}}} -\def\@defthm#1#2{\refstepcounter - {#1}\@ifnextchar[{\@ydefthm{#1}{#2}}{\@xdefthm{#1}{#2}}} -\def\@xdefthm#1#2{\@begindef{#2}{\csname the#1\endcsname}\ignorespaces} -\def\@ydefthm#1#2[#3]{\trivlist \item[\hskip 10pt\hskip - \labelsep{\it #2\savebox\@tempboxa{#3}\ifdim - \wd\@tempboxa>\z@ \ \box\@tempboxa\fi.}]\ignorespaces} -\def\@begindef#1#2{\trivlist \item[\hskip 10pt\hskip - \labelsep{\it #1\ \rm #2.}]} -% -\def\theequation{\arabic{equation}} -% -\def\titlepage{\@restonecolfalse\if@twocolumn\@restonecoltrue\onecolumn - \else \newpage \fi \thispagestyle{empty}\c@page\z@} -\def\endtitlepage{\if@restonecol\twocolumn \else \newpage \fi} -% -\arraycolsep 2.5pt \tabcolsep 6pt \arrayrulewidth .4pt \doublerulesep 2pt -\tabbingsep \labelsep -% -\skip\@mpfootins = \skip\footins -\fboxsep = 3pt \fboxrule = .4pt -% -\newcounter{part} -\newcounter{section} -\newcounter{subsection}[section] -\newcounter{subsubsection}[subsection] -\newcounter{paragraph}[subsubsection] -% -\def\thepart{\Roman{part}} -\def\thesection {\arabic{section}} -\def\thesubsection {\thesection.\arabic{subsection}} -\def\thesubsubsection {\itshape\thesubsection.\arabic{subsubsection}} -\def\theparagraph {\thesubsubsection.\arabic{paragraph}} - -\def\@pnumwidth{1.55em} -\def\@tocrmarg {2.55em} -\def\@dotsep{4.5} -\setcounter{tocdepth}{3} - -\def\tableofcontents{\section*{Contents\@mkboth{CONTENTS}{CONTENTS}} - \@starttoc{toc}} -\def\l@part#1#2{\addpenalty{\@secpenalty} - \addvspace{2.25em plus 1pt} \begingroup - \@tempdima 3em \parindent \z@ \rightskip \@pnumwidth \parfillskip --\@pnumwidth - {\large \bf \leavevmode #1\hfil \hbox to\@pnumwidth{\hss #2}}\par - \nobreak \endgroup} -\def\l@section#1#2{\addpenalty{\@secpenalty} \addvspace{1.0em plus 1pt} -\@tempdima 1.5em \begingroup - \parindent \z@ \rightskip \@pnumwidth - \parfillskip -\@pnumwidth - \bf \leavevmode #1\hfil \hbox to\@pnumwidth{\hss #2}\par - \endgroup} -\def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} -\def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} -\def\listoffigures{\section*{List of Figures\@mkboth - {LIST OF FIGURES}{LIST OF FIGURES}}\@starttoc{lof}} -\def\l@figure{\@dottedtocline{1}{1.5em}{2.3em}} -\def\listoftables{\section*{List of Tables\@mkboth - {LIST OF TABLES}{LIST OF TABLES}}\@starttoc{lot}} -\let\l@table\l@figure -% -\newif\if@restonecol -\def\theindex{\@restonecoltrue\if@twocolumn\@restonecolfalse\fi -\columnseprule \z@ -\columnsep 35pt\twocolumn[\section*{Index}] - \@mkboth{INDEX}{INDEX}\thispagestyle{plain}\parindent\z@ - \parskip\z@ plus .3pt\relax\let\item\@idxitem} -\def\@idxitem{\par\hangindent 40pt} -\def\subitem{\par\hangindent 40pt \hspace*{20pt}} -\def\subsubitem{\par\hangindent 40pt \hspace*{30pt}} -\def\endtheindex{\if@restonecol\onecolumn\else\clearpage\fi} -\def\indexspace{\par \vskip 10pt plus 5pt minus 3pt\relax} -% -\def\footnoterule{\kern-3\p@ - \hrule \@height 0.2\p@ \@width 47\p@ - \kern 2.6\p@ -} - -\long\def\@makefntext#1{\parindent 1em\noindent - $^{\@thefnmark}$#1} -% -\setcounter{topnumber}{3} -\def\topfraction{.99} -\setcounter{bottomnumber}{1} -\def\bottomfraction{.5} -\setcounter{totalnumber}{3} -\def\textfraction{.01} -\def\floatpagefraction{.85} -\setcounter{dbltopnumber}{2} -\def\dbltopfraction{.95} -\def\dblfloatpagefraction{.96} -% -\long\def\@makecaption#1#2{\vskip 1pc \setbox\@tempboxa\hbox{#1.\hskip -1em\relax #2} - \ifdim \wd\@tempboxa >\hsize #1. #2\par \else \hbox -to\hsize{\hfil\box\@tempboxa\hfil} - \fi} - -\def\nocaption{\refstepcounter\@captype \par - \vskip 1pc \hbox to\hsize{\hfil \footnotesize Figure \thefigure - \hfil}} -% -\newcounter{figure} -\def\thefigure{\@arabic\c@figure} -\def\fps@figure{tbp} -\def\ftype@figure{1} -\def\ext@figure{lof} -\def\fnum@figure{Fig.\ \thefigure}% -\def\figure{\let\normalsize\footnotesize\normalsize\@float{figure}} -\let\endfigure\end@float -\@namedef{figure*}{\@dblfloat{figure}} -\@namedef{endfigure*}{\end@dblfloat} -% -\newcounter{table} -\def\thetable{\@arabic\c@table} -\def\fps@table{tbp} -\def\ftype@table{2} -\def\ext@table{lot} -\newlength\belowcaptionskip -\setlength\belowcaptionskip{1\p@} -% -\def\FigName{figure}% -\long\def\@caption#1[#2]#3{\par\begingroup - \@parboxrestore - \normalsize \bf \centering - \@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par - \endgroup} -% -% -\newbox\tbbox -\long\def\@makecaption#1#2{% - \ifx\FigName\@captype - \vskip 7.3pt - \setbox\@tempboxa\hbox{\figcaptionfont{#1}.\hskip7.3pt\relax #2\par}% - \ifdim \wd\@tempboxa >\hsize - \figcaptionfont{#1}.\hskip7.3pt\relax #2\par - \else - \centerline{\box\@tempboxa}% - \fi - \else% - \setbox\tbbox=\vbox{\hsize\tempdimen{\tablenumfont #1}\ {\tablecaptionfont #2\par}}% - \setbox\@tempboxa\hbox{\hsize\tempdimen{\tablenumfont #1}\ {\tablecaptionfont #2\par}\vphantom{jgq}}% - \ifdim \wd\@tempboxa >\tempdimen - \centerline{\box\tbbox}% - \else - \centerline{\box\@tempboxa}% - \fi - \vskip\belowcaptionskip - \fi} -% -\def\fnum@table{Table~\thetable.\ } -\def\table{\let\normalsize\footnotesize \normalsize\@float{table}} -\let\endtable\end@float -\@namedef{table*}{\@dblfloat{table}} -\@namedef{endtable*}{\end@dblfloat} -\def\ijcatable#1{\@narrowfig #1\relax - \let\caption\@atcap \let\nocaption\@atnocap - \def\@tmpnf{}\@ifnextchar[{\@xntab}{\@ntab}} -\def\endijcatable{\hbox to \textwidth{\hfil -\vbox{\hsize \@narrowfig -\box\@nfcapbox -{\baselineskip 4pt \hbox{\vrule height .4pt width \hsize}} -\vskip -1pt -\box\@nfigbox\vskip -1pt -{\baselineskip 4pt \hbox{\vrule height .4pt width \hsize}}}\hfil} -\end@float} -\def\@xntab[#1]{\def\@tmpnf{[#1]}\@ntab} -\def\@ntab{\expandafter\table\@tmpnf - \setbox\@nfigbox\vbox\bgroup - \hsize \@narrowfig \@parboxrestore} -\def\@atmakecap #1#2{\setbox\@tempboxa\hbox{#1.\hskip 1em\relax #2} - \ifdim \wd\@tempboxa >\hsize \sloppy #1.\hskip 1em\relax #2 \par \else \hbox -to\hsize{\hfil\box\@tempboxa\hfil} - \fi} -\def\@atcap{\par\egroup\refstepcounter\@captype - \@dblarg{\@atcapx\@captype}} -\long\def\@atcapx#1[#2]#3{\setbox\@nfcapbox\vbox {\hsize \wd\@nfigbox - \@parboxrestore - \@atmakecap{\csname fnum@#1\endcsname}{\ignorespaces #3}\par}} -\def\@atnocap{\egroup \refstepcounter\@captype - \setbox\@nfcapbox\vbox {\hsize \wd\@nfigbox - \hbox to\hsize{\hfil \footnotesize Table \thetable\hfil}}} -% -\newdimen\tabledim -% -\long\def\tbl#1#2{% - \setbox\tempbox\hbox{\tablefont #2}% - \tabledim\hsize\advance\tabledim by -\wd\tempbox - \tempdimen\wd\tempbox - \global\divide\tabledim\tw@ - \caption{#1} - \centerline{\box\tempbox} - }% -% -\newenvironment{tabnote}{% -\par%\addvspace{-1pt} -\tabnotefont -\@ifnextchar[{\@tabnote}{\@tabnote[]}}{% -\par} -\def\@tabnote[#1]{\def\@Tempa{#1}\leftskip\tabledim\rightskip\leftskip\ifx\@Tempa\@empty\else{\it #1:}\ \fi\ignorespaces} -% -\def\tabnoteentry#1#2{\parindent0pt\par\@hangfrom{#1}{#2}} -\def\Note#1#2{\parindent0pt\par\hangindent3.7pt{\it #1}\ #2} -% - -\def\Hline{% - \noalign{\ifnum0=`}\fi\hrule \@height .5pt \futurelet - \@tempa\@xhline} -% -\def\narrowfig#1{\@narrowfig #1\relax - \let\caption\@nfcap \let\nocaption\@nfnocap - \def\@tmpnf{}\@ifnextchar[{\@xnfig}{\@nfig}} -\def\endnarrowfig{\hbox to \textwidth{\if@nfeven - \box\@nfcapbox\hfil\box\@nfigbox - \else \box\@nfigbox\hfil\box\@nfcapbox\fi}\end@float} -\def\@xnfig[#1]{\def\@tmpnf{[#1]}\@nfig} -\def\@nfig{\expandafter\figure\@tmpnf - \setbox\@nfigbox\vbox\bgroup - \hsize \@narrowfig \@parboxrestore} -\def\@nfmakecap #1#2{\setbox\@tempboxa\hbox{#1.\hskip 1em\relax #2} - \ifdim \wd\@tempboxa >\hsize \sloppy #1.\hskip 1em\relax #2 \par \else \hbox -to\hsize{\if@nfeven\else\hfil\fi\box\@tempboxa\if@nfeven\hfil\fi} - \fi} -\def\@nfcap{\par\egroup\refstepcounter\@captype - \@dblarg{\@nfcapx\@captype}} -\long\def\@nfcapx#1[#2]#3{\@seteven - \setbox\@nfcapbox\vbox to \ht\@nfigbox - {\hsize \textwidth \advance\hsize -2pc \advance\hsize -\wd\@nfigbox - \@parboxrestore - \vfil - \@nfmakecap{\csname fnum@#1\endcsname}{\ignorespaces #3}\par - \vfil}} -\def\@nfnocap{\egroup \refstepcounter\@captype \@seteven - \setbox\@nfcapbox\vbox to \ht\@nfigbox - {\hsize \textwidth \advance\hsize -2pc \advance\hsize -\wd\@nfigbox - \@parboxrestore - \vfil - \hbox to\hsize{\if@nfeven\else\hfil\fi - \footnotesize Figure \thefigure - \if@nfeven\hfil\fi} - \vfil}} -\def\@seteven{\@nfeventrue - \@ifundefined{r@@nf\thefigure}{}{% - \edef\@tmpnf{\csname r@@nf\thefigure\endcsname}% - \edef\@tmpnf{\expandafter\@getpagenum\@tmpnf}% - \ifodd\@tmpnf\relax\@nfevenfalse\fi}% -\label{@nf\thefigure}\edef\@tmpnfx{\if@nfeven e\else o\fi} -\edef\@tmpnf{\write\@unused {\noexpand\ifodd \noexpand\c@page - \noexpand\if \@tmpnfx e\noexpand\@nfmsg{\thefigure} \noexpand\fi - \noexpand\else - \noexpand\if \@tmpnfx o\noexpand\@nfmsg{\thefigure}\noexpand\fi - \noexpand\fi }}\@tmpnf} -\def\@nfmsg#1{Bad narrowfig: Figure #1 on page \thepage} - -\newdimen\@narrowfig -\newbox\@nfigbox -\newbox\@nfcapbox -\newif\if@nfeven - - -\def\maketitle{% - \thispagestyle{titlepage}% - \newpage - \global\@topnum\z@ - \twocolumn[\@maketitle]% - \let\maketitle\relax - \global\let\@sponsors\@empty -} -% -\def\@maketitle{\newpage \thispagestyle{titlepage}\par - \begingroup \lineskip = \z@\null - \vspace{-1.75em} - \begin{picture}(5,5) - \includegraphics[width=1in]{logojuliacon.pdf} - \end{picture} - \vspace{1.75em} - \vskip -7pt\relax %-18.5pt - \parindent\z@ \LARGE {\centering \hyphenpenalty\@M - {\titlefont \@title} \par - \global\firstfoot %aiellom - \global\runningfoot %aiellom -} -\label{@firstpg} -{ -\begin{center}% - \vskip 0.1em% - {\large - \lineskip .75em% - \begin{tabular}[t]{c}% - \@author - \end{tabular}\par}% - \vskip 1.5em% - \end{center}\par - \@thanks -} - \vskip 23pt\relax - \endgroup - } -\newbox\@abstract -\newbox\@terms -\newbox\@keywords - - -% -\newenvironment{abstract} -{\section*{ABSTRACT}\par\fontsize{10}{12}\indent\ignorespaces} -{ - { \ifvoid\@terms\else\box\@terms\fi - \@keywords \@juliaconformat\empty}\vskip6pt} -% -\def\terms#1{\setbox\@terms=\vbox{\hsize20pc% - \footnotesize% - \parindent 0pt \noindent - { \section*{General Terms}} \ignorespaces #1{\vspace{-0.75em}}}} -\def\keywords#1{\gdef\@keywords{\hsize20pc% - \parindent 0pt\noindent\ignorespaces% - {{\vspace{-0.75em}} \section*{Keywords}} \ignorespaces #1{\vspace{1em}}}} -%} - -\def\category#1#2#3{\@ifnextchar - [{\@category{#1}{#2}{#3}}{\@xcategory{#1}{#2}{#3}}} -\def\@category#1#2#3[#4]{\edef\@tempa{\ifx \@categories\@empty - \else ; \fi}{\def\protect{\noexpand\protect - \noexpand}\def\and{\noexpand\and}\xdef\@categories{\@categories\@tempa #1 -[{\bf #2}]: - #3\kern\z@---\hskip\z@{\it #4}}}} -\def\@xcategory#1#2#3{\edef\@tempa{\ifx \@categories\@empty \else ; -\fi}{\def\protect{\noexpand\protect\noexpand}\def\and{\noexpand - \and}\xdef\@categories{\@categories\@tempa #1 [{\bf #2}]: #3}}} -\def\@categories{} - -\newenvironment{ackslike}[1] - {\par \footnotesize - \@ucheadfalse - \@startsection{subsection}{2}{\z@}{-16pt plus -2pt minus -1pt}{2pt}{\sf}* - {\uppercase{#1}}\par\normalsize - } - {\par} -\newenvironment{acks}{\begin{ackslike}{ \normalsize\rm\bf Acknowledgments}}{\end{ackslike}} -% - -\newcommand\headingtable{% - \begin{tabular}[b]{l} {\@journalName}\end{tabular}} -\markright{\protect\headingtable} -\mark{{}{}} -\def\bull{{\fontsize{7}{7}\selectfont\raise1.6pt\hbox{$\bullet$}}} -\def\ps@myheadings{\let\@mkboth\@gobbletwo -\def\@oddhead{ \fontsize{9}{12} \rm {{\itshape\headingtable}\hfill \@volume(\@issue), \@year}} -\def\@oddfoot{\fontsize{9}{12}\@runningfoot} -\def\@evenhead{ \fontsize{9}{12} \rm {\itshape\headingtable}\hfill \@volume(\@issue), \@year} -\def\@evenfoot{\fontsize{9}{12}\@runningfoot} -\def\sectionmark##1{}\def\subsectionmark##1{}} -% -\def\@runningfoot{} -\def\runningfoot{\def\@runningfoot{ \fontsize{9}{12} \thepage}} -\def\@firstfoot{} -\def\firstfoot{\def\@firstfoot{\fontsize{9}{12} \thepage}} -\def\ps@titlepage{\let\@mkboth\@gobbletwo -\def\@oddhead{}\def\@oddfoot{\fontsize{9}{12}\@firstfoot}\def\@evenhead{}\def\@evenfoot{\fontsize{9}{12}\@firstfoot}} -% -\def\today{\ifcase\month\or - January\or February\or March\or April\or May\or June\or - July\or August\or September\or October\or November\or December\fi - \space\number\day, \number\year} -\def\@marrayclassiv{\@addtopreamble{$\displaystyle \@nextchar$}} -\def\@marrayclassz{\ifcase \@lastchclass \@acolampacol \or \@ampacol \or - \or \or \@addamp \or - \@acolampacol \or \@firstampfalse \@acol \fi -\edef\@preamble{\@preamble - \ifcase \@chnum - \hfil$\relax\displaystyle\@sharp$\hfil \or $\relax\displaystyle\@sharp$\hfil - \or \hfil$\relax\displaystyle\@sharp$\fi}} -\def\marray{\arraycolsep 2.5pt\let\@acol\@arrayacol \let\@classz\@marrayclassz - \let\@classiv\@marrayclassiv \let\\\@arraycr\def\@halignto{}\@tabarray} -\def\endmarray{\crcr\egroup\egroup} -% -\ps@myheadings \pagenumbering{arabic} \onecolumn -% -\setlength \labelsep {.5em} -\setlength \labelwidth{\leftmargini} -\addtolength\labelwidth{-\labelsep} -\@beginparpenalty -\@lowpenalty -\@endparpenalty -\@lowpenalty -\@itempenalty -\@lowpenalty -% -\def\newdef#1{\@ifnextchar[{\@xnewdef{#1}}{\@ynewdef{#1}}} -\def\@xnewdef#1[#2]#3{\newtheorem{italic@#1}[#2]{{\em #3}}\@newdef{#1}} -\def\@ynewdef#1#2{\@ifnextchar[{\@xynewdef{#1}{#2}}{\@yynewdef{#1}{#2}}} -\def\@xynewdef#1#2[#3]{\newtheorem{italic@#1}{{\em #2}}[#3]\@newdef{#1}} -\def\@yynewdef#1#2{\newtheorem{italic@#1}{{\em #2}}\@newdef{#1}} -\def\@newdef#1{\newenvironment{#1}{\@ifnextchar[{\@xstartdef{#1}}{\@ystartdef{#1}}}{\end{italic@#1}}} -\def\@xstartdef#1[#2]{\begin{italic@#1}[{\em #2}]\rm} -\def\@ystartdef#1{\begin{italic@#1}\rm} -% -%\def\@oddfoot{\hbox{}\hfill\@runningfoot \thepage} -%\def\@evenfoot{\@runningfoot\hfill\hbox{} \thepage } -%\def\firstfootsize{\@setsize\firstfootsize{9pt}\vipt\@vipt} -\def\ps@titlepage{\let\@mkboth\@gobbletwo -\def\@oddhead{\fontsize{9}{12} \rm {\hskip 19pt\itshape}}\def\@oddfoot{\hbox{}\hfill\fontsize{9}{12}\@firstfoot}% -\def\@evenhead{}\def\@evenfoot{\firstfootsize\@firstfoot\hfill\hbox{}}} -% -\def\@listI{\leftmargin\leftmargini - \labelwidth\leftmargini\advance\labelwidth-\labelsep - \parsep 0pt plus 1pt - \topsep 6pt plus 2pt minus 2pt - \itemsep 2pt plus 1pt minus .5pt} -\let\@listi\@listI -\@listi -% -\def\longenum{\ifnum \@enumdepth >3 \@toodeep\else - \advance\@enumdepth \@ne - \edef\@enumctr{enum\romannumeral\the\@enumdepth}\list - {\csname label\@enumctr\endcsname}{\usecounter - {\@enumctr}\labelwidth\z@\leftmargin\z@ - \itemindent\parindent \advance\itemindent\labelsep}\fi} -% -\def\ack{ \par \footnotesize -\@ucheadfalse -\@startsection{subsection}{2}{\z@}{-16pt plus -2pt minus - -1pt}{2pt}{\sf}*{ACKNOWLEDGMENT}\par\normalsize -} -\def\endack{\par} - -% provide both spellings of Acknowledgment(s) -\let\acknowledgments\acks -\let\endacknowledgments\endacks -\let\acknowledgment\ack -\let\endacknowledgment\endack -% -\newcommand{\bibemph}[1]{{\em#1}} -\newcommand{\bibemphic}[1]{{\em#1\/}} -\newcommand{\bibsc}[1]{{\sc#1}} - -\newcommand\bibyear[2]{% - \unskip{\hskip8pt}\ignorespaces#1\unskip - \if..#2{\hskip6pt}\else {\hskip8pt}#2 \fi -} -% -\let\l@table\l@figure -\newdimen\bibindent -\setlength\bibindent{1.5em} -\newenvironment{thebibliography}[1] - {\section{\refname}%% - \list{\@biblabel{\@arabic\c@enumiv}}% - {\settowidth\labelwidth{\@biblabel{#1}}% - \leftmargin\labelwidth - \advance\leftmargin\labelsep - \@openbib@code - \usecounter{enumiv}% - \let\p@enumiv\@empty - \renewcommand\theenumiv{\@arabic\c@enumiv}}% - \sloppy - \clubpenalty4000 - \@clubpenalty \clubpenalty - \widowpenalty4000% - \sfcode`\.\@m} - {\def\@noitemerr - {\@latex@warning{Empty `thebibliography' environment}}% - \endlist} -\newcommand\newblock{\hskip .11em\@plus.33em\@minus.07em} -\let\@openbib@code\@empty - -% -\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} -\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} -\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} -\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} -\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} -\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} -\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} -\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} -\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} -% -\def\@juliaconformat{} -\def\juliaconformat#1{\gdef\@juliaconformat{\noindent{\bf JuliaCon Reference Format:}\\[2pt] #1\par}} -% -\def\received#1#2{% - \par% - \tiny - \addvspace{12\p@}% - \parindent\z@% -\small\scriptsize{Received\ #1;\ accepted\ #2}% -\par% -} - -% -\sloppy -\clubpenalty10000 -\widowpenalty10000% -\@lowpenalty 51 -\@medpenalty 151 -\@highpenalty 301 -% -\@beginparpenalty -\@lowpenalty -\@endparpenalty -\@lowpenalty -\@itempenalty -\@lowpenalty - -\voffset-5pc -\hoffset-6.03pc - -\usepackage{times} -%% \usepackage[mtbold]{mathtime} -\usepackage{bm} -\usepackage{graphicx}% Include figure files -\usepackage{hyperref} -%%\usepackage{microtype} -\renewcommand{\ttdefault}{cmtt} - -\usepackage{jlcode} - -\usepackage{authblk} - -\endinput - -% end of juliacon.cls diff --git a/paper/logojuliacon.pdf b/paper/logojuliacon.pdf deleted file mode 100644 index 744eaee..0000000 Binary files a/paper/logojuliacon.pdf and /dev/null differ diff --git a/paper/paper.tex b/paper/paper.tex deleted file mode 100644 index 55bcd0b..0000000 --- a/paper/paper.tex +++ /dev/null @@ -1,599 +0,0 @@ -% JuliaCon proceedings template -\documentclass{juliacon} -\setcounter{page}{1} - -\usepackage{xspace} - -\usepackage{subcaption} - -\usepackage{hyperref} - -% \usepackage{placeins} - -% \usepackage{float} - -\hypersetup{colorlinks=false,linkcolor=blue,urlcolor=blue} - -\newcommand{\ie}{\emph{i.e.}} -\newcommand{\cp}{\textsc{CP}\xspace} -\newcommand{\csp}{\textsc{CSP}\xspace} -\newcommand{\cop}{\textsc{COP}\xspace} -\newcommand{\efsp}{\textsc{EFSP}\xspace} -\newcommand{\efop}{\textsc{EFOP}\xspace} -\newcommand{\cfn}{\textsc{CFN}\xspace} -\newcommand{\wcsp}{\textsc{WCSP}\xspace} -\newcommand{\cbls}{\textsc{CBLS}\xspace} -\newcommand{\ghost}{\textsc{GHOST}\xspace} -\newcommand{\cppn}{\textsc{CPPN}\xspace} -\newcommand{\icn}{\textsc{ICN}\xspace} - -\newcommand{\jc}{\href{https://github.com/JuliaConstraints}{JuliaConstraints}\xspace} -\newcommand{\cdjl}{\href{https://github.com/JuliaConstraints/ConstraintDomains.jl}{ConstraintDomains.jl}\xspace} -\newcommand{\cnjl}{\href{https://github.com/JuliaConstraints/CompositionalNetworks.jl}{CompositionalNetworks.jl}\xspace} -\newcommand{\cjl}{\href{https://github.com/JuliaConstraints/Constraints.jl}{Constraints.jl}\xspace} -\newcommand{\cmjl}{\href{https://github.com/JuliaConstraints/ConstraintModels.jl}{ConstraintModels.jl}\xspace} -\newcommand{\lssjl}{\href{https://github.com/JuliaConstraints/LocalSearchSolvers.jl}{LocalSearchSolvers.jl}\xspace} -\newcommand{\cblsjl}{\href{https://github.com/JuliaConstraints/CBLS.jl}{CBLS.jl}\xspace} -\newcommand{\icnbjl}{\href{https://github.com/JuliaConstraints/ICNBenchmarks.jl}{ICNBenchmarks.jl}\xspace} - - -\newcommand{\cproblem}[3]% -{\begin{trivlist} - \item[]% - \textbf{Problem:} \textsc{#1}\\ - \textit{Input:} #2\\ - \textit{Question:} #3 - \end{trivlist}% -} - -\begin{document} - -\input{header} - -\maketitle - -\begin{abstract} - Interpretable Compositional Networks (ICNs) are a neural network variant for combinatorial function learning that allows the user to obtain interpretable results, unlike ordinary artificial neural networks. An ICN outputs a composition of functions that scales with the size of the input, allowing a learning phase on relatively small spaces. - \cnjl is a pure Julia package that exploits the language's meta-programming, parallelism and multiple dispatch features to produce learned compositions in mathematical and programming languages such as Julia, C or C++. -\end{abstract} - -\section{Introduction} -\label{sec:introduction} - -The discipline of combinatorial optimization consists in finding an optimal configuration of elements within a finite set. Such a set is usually subject to constraints that can be represented by functions that are often highly combinatorial. These constraints are mostly formulated as concepts, boolean functions indicating whether each constraint is respected or not. A solution (sometimes called a satisfying solution, depending on the field) is a configuration that respects all the constraints. - -Different domains such as operational research, constraint programming, metaheuristics, propose methods to find (satisfactory or optimal) solutions. Among these methods, some can or could benefit from a finer granularity in the evaluation of the impact of each constraint on a given configuration. - -In \cite{richoux2020automatic}, we introduced Interpretable Compositional Networks (ICNs), a neural network variant for combinatorial function learning that allows the user to obtain interpretable results, unlike ordinary artificial neural networks. An ICN outputs a composition of functions that scale with the size of the input, allowing a learning phase on relatively small spaces. - -This work consists in a library that implements ICNs in the Julia programming language \cite{bezanson2017julia}. Although we present a direct application of ICNs in the following subsection, this neural network framework is simple to extend to learn other combinatorial and non-combinatorial functions. - -\subsection{Application to Constraint Programming} -\label{subsec:cpcontext} - -Constraint Satisfaction Problem (\csp) and Constrained Optimization Problem (\cop) are constraint-based problems where constraints can be seen as predicates (\emph{concepts}) allowing or forbidding some combinations of variable assignments. -Such a formulation corresponds well to the so-called complete solution methods which guarantee an exploration of all solutions. Unfortunately, due to the highly combinatorial nature of some problems, these methods cannot always converge in a reasonable time. - -\begin{figure}[t] - \centerline{\includegraphics[width=5cm]{figs/juliaconstraints.png}} - \caption{Logo of the \jc organization on GitHub that hosts, among other things, the \cnjl package.} - \label{fig:juliaconstraints} -\end{figure} - -On the other hand, Constraint-Based Local Search (\cbls) is a family of metaheuristics in which the neighborhood is constructed on the basis of an \emph{error function}, itself a quantitative representation of how far the current configuration is from an admissible solution. We refer to the corresponding problems as Error Function Satisfaction Problem (\efsp) and Error Function Optimization Problem (\efop). In the case of \cbls, this is computed as a function of the constraints which are not currently satisfied. Error functions may be derived from the constraint satisfaction problem structure, hand-coded, automatically acquired by some machine learning process, or constructed as a combination of these methods. It should be noted that, the best performing systems resort to hand-tuned error functions, as witness~\cite{DBLP:books/sp/18/CodognetMDA18}. - -As illustrated by Figure~\ref{fig:landscape}, a well-designed error function helps in converging faster towards better-quality solutions. It does, however, introduce an additional layer of complexity to the user. - -\begin{figure*}[t] - \centering - \subcaptionbox{CSP landscape\label{sfig:csp}}{ - \includegraphics[width = .95\columnwidth]{figs/csp_landscape_complex_zero_big.png} - } - \hfill - \subcaptionbox{EFSP landscape\label{sfig:efsp}}{ - \includegraphics[width = .95\columnwidth]{figs/efsp_landscape_complex_zero_big.png} - }\caption{ - Comparison of a Constraint Satisfaction Problem (CSP) and an Error - Function Satisfaction Problem (\efsp) landscapes. The finer scale - in the error heuristic of the \efsp leads to a better convergence - rate.}\label{fig:landscape} -\end{figure*} - -\subsection{Interpretable Compositional Networks (ICN)} -\label{subsec:icn} - -In \cite{richoux2020automatic}, we proposed a neural network inspired by Compositional Pattern-Producing Networks (\cppn) to learn (highly) combinatorial functions as non-linear combinations of elementary operations. \(\cppn\)s~\cite{stanley2007cppn} are themselves a variant of artificial neural networks. While neurons in regular neural networks usually contain sigmoid-like functions only (such as ReLU, \ie{} Rectified Linear Unit), \cppn's neurons can contain many other kinds of functions: sigmoids, Gaussians, trigonometric functions, and linear functions among others. -\(\cppn\)s are often used to generate 2D or 3D images by applying the function modeled by a \cppn giving each pixel individually as input, instead of considering all pixels at once. This simple trick allows the learned \cppn model to produce images of any resolution. - -We propose our variant by taking these two principles from \cppn: having neurons containing one operation among many possible ones, and handling inputs in a size-independent fashion. Due to their interpretable nature, we named our variant \textbf{Interpretable Compositional Networks} (\icn). - -Although ICNs are not limited to learning function for \efsp/\efop, the original structure was designed to learn compositions weighted in accordance to the hamming metric \cite{richoux2020automatic}. The hamming distance between a configuration and its closest solution is a meaningful indicator of the number of variables needed to be changed. Manhattan and other variants of minkowski comparison are other example of possible metrics. - -An ICN is made of several layers of (possibly exclusive) operations such that the first layers accept a vector as input and the last layer returns a single numerical value. Generally, layers alter there input in three possible ways: \emph{increment}, \emph{decrement}, or \emph{conservation} of the dimension of the input. - -\begin{figure}[t] - \centerline{\includegraphics[width=\columnwidth]{figs/model_nn.png}} - \caption{Scheme of the basic 4-layers ICN model used in \efsp/\efop. Layers with blue neurons have mutually exclusive operations. the \emph{transformation} layer increases the input dimension, the \emph{arithmetic} and \emph{aggregation} layers reduces it, and the \emph{comparison} layer leaves it untouched. The figure is taken from \cite{richoux2020automatic}.} - \label{fig:model_icn} -\end{figure} - -In the context of \efsp/\efop, the output should be non-negative if the constraint is violated and equal to 0 otherwise. As shown by Figure \ref{fig:model_icn}, our \(\icn\)s are -composed of four layers, each of them having a specific purpose and -themselves composed of neurons applying a unique operation each. All -neurons from a layer are linked to all neurons from the next -layer. The weight on each link is purely binary: its value is either 0 -or 1. This restriction is crucial to obtain interpretable functions. We refer the reader to \cite{richoux2020automatic} for a more comprehensive definition. - -% \subsection{A first C++ library} -% \label{subsec:cplusplus} - -In \cite{richoux2020automatic} we introduced the concept of ICN and a first implementation for Constraint Programming as a C++ library\footnote{\url{https://github.com/richoux/LearningUtilityFunctions}}. The results were evaluated through the GHOST C++ solver \cite{richoux2016ghost} and serve as a proof of concept that most of the models give scalable functions, and remain fairly effective using incomplete training sets. - -As mentioned in Section \ref{sec:use}, \cnjl generates code for a direct use in Julia, but also exports usable code for both the GHOST(C++) and AdaptiveSearch (C)\footnote{This feature is a WIP at the moment this article is submitted, but is expected to be completed in the coming weeks.}. The code exported in C++, that is the \emph{operations} of each neuron, is strongly inspired by our C++ library. - -This work is part of a collection of articles that introduce the theoretical background of ICN \cite{richoux2020automatic}, a user-friendly implementation in Julia, and an extensive collection of benchmarks \cite{baffier2022interpretable}. -Please note that the default parameters, and semi-automated learning parameters for advanced users, in \cnjl will improve along the results in \cite{baffier2022interpretable} computed from \icnbjl on an HPC cluster. - -\begin{figure*}[t] - \centerline{\includegraphics[page=1, width=.9\textwidth]{figs/overview.pdf}} - \caption{Overview of the Constraint Programming ecosystem in Julia, including \jc. \emph{Front-End} and \emph{Internals} refer to the latest. Note that, at the moment of the writing, \texttt{ConstraintProgrammingExtension.jl}, \texttt{JuCP.jl}, and \texttt{COPInstances.jl} are temporary names.} - \label{fig:overview} -\end{figure*} - -% \FloatBarrier - -\section{The example of the \jc framework} -\label{sec:juliaconstraints} - -The \cnjl package is part of the \jc GitHub organization that proposes a first collection of Julia packages for Constraint-Based Local Search (CBLS), a subfield of Constraint Programming. All packages fall under the MIT license. - -The main goal of this framework is to provide a set of high level semi-automatic tools which strike a good compromise between efficiency and ease of modeling. - -\subsection{History of \jc} -\label{subsec:history} - -The \lssjl package is a Constraint-Based Local Search framework started in Fall 2020 and inspired by other CBLS solvers such as GHOST (C++) and AdaptiveSearch (C) that allows users to tune their own solver. - -During the development of LocalSearchSolvers.jl, we decided to split the code and functionality of the original framework into several independent packages for ease of maintenance and in hopes of providing common tools for other constraint programming packages in Julia. These tools were collected into the \jc ecosystem. - -The global state of the Constraint Programming ecosystem is presented in Figure \ref{fig:overview}. Beside the CBLS framework of \jc detailed below, other solvers are complete search methods, such as ConstraintSolver.jl\footnote{\url{https://github.com/Wikunia/ConstraintSolver.jl}}, CPLEXCP.jl\footnote{\url{https://github.com/dourouc05/CPLEXCP.jl}}, and SeaPearl.jl \cite{chalumeau2021seapearl}. - -\paragraph*{State of the packages in \jc} - -\begin{itemize} - \item Stable packages - \begin{itemize} - \item \cnjl: internal tool to provide semi-automated error functions. Also, a standalone to learn compositions for combinatorial functions\footnote{At the time of submission, \cnjl is not yet release as \texttt{v1}. Some minor changes are expected from the results of the benchmarks in \cite{baffier2022interpretable} that will be submitted at the end of October.} - \end{itemize} - \item Beta packages (usable with frequent breaking changes) - \begin{itemize} - \item \cdjl: creation of discrete, continuous, and arbitrary domains - \item \cjl: generation of constraints from a boolean concept or an error function. Also, list usual constraints and their properties - \item \lssjl: A CBLS framework in Julia with built-in parallel and distributed scalability - \item \cblsjl: A MOI/JuMP wrapper for LocalSearchSolvers - \item \cmjl: list of CP models for \cblsjl and \lssjl - \end{itemize} - -\end{itemize} - - - -\subsection{The \emph{JuMP} ecosystem} % 3-6p -\label{subsec:jump} - -JuMP is a modeling language accessible through its main package -JuMP.jl \cite{DunningHuchetteLubin2017} and many supporting Julia packages. Beneath JuMP is an -abstraction layer called MathOptInterface -(MOI)~\cite{MathOptInterface-2021}. One can make a parallel -between MOI/JuMP and FlatZinc/MiniZinc~\cite{nethercote2007minizinc}, -common modeling tools of the Constraint Programming community. -Recently, the -\href{https://github.com/dourouc05/ConstraintProgrammingExtensions.jl}{ConstraintProgrammingExtensions.jl} -package that extends MOI/JuMP to the Constraint Programming world was -made available. It is likely to become the recommended unified JuMP -modeling extension for the Julia Constraint Programming solvers. - -\subsection{A simple example with \texttt{CBLS.jl}} -\label{subsec:example} - -\begin{figure}[t] - \centerline{\includegraphics[page=1, width=.75\columnwidth]{figs/magicsquare.pdf}} - \caption{A solved magic-square of size $3$. The \emph{magic sum} is equal to $15$. Image from Wikipedia's user \textsc{Phidauex}.} - \label{fig:magicsquare} -\end{figure} - -Our CBLS framework uses three levels of modeling syntax: a \emph{raw} Julia syntax, and both MOI and JuMP syntaxes. In this article, we will only use the highest level one, the JuMP syntax. - -A Magic Square of order $n$ is composed of $n^2$ distinct values ranging from $1$ to $n^2$ layed out as a square array $X$. These values need to be arranged such that the sums of each diagonal, row and column be equal to the same value, the magic sum $\Sigma$. - -\[ \sum_{j=1}^{n} X_{ij} = \sum_{i=1}^{n} X_{ij} = \sum_{j=1}^{n} X_{ii} = \sum_{j=1}^{n} X_{i,n-i+1} = \frac{n(n^{2}+1)}{2} = \Sigma \] - -In \cmjl, we use the following code to generate a magic-square instance. - -\begin{lstlisting}[language = Julia] -# Import CBLS.jl and JuMP.jl -using CBLS, JuMP - -function magic_square(n::Integer) -model = Model(CBLS.Optimizer) -N = n^2 -Σ = n * (N + 1) / 2 -@variable(model, 1 <= X[1:n, 1:n] <= N, Int) -@constraint(model, vec(X) in AllDifferent()) -for i in 1:n - @constraint(model, X[i,:] in Linear(Σ)) - @constraint(model, X[:,i] in Linear(Σ)) -end -@constraint(model, - [X[i,i] for i in 1:n] in Linear(Σ) -) -@constraint(model, - [X[i,n+1-i] for i in 1:n] in Linear(Σ) -) - return model, X -end -\end{lstlisting} - -\section{A flexible implementation} -\label{sec:implementation} - -As mentioned in Subsection \ref{subsec:icn}, \cnjl extends the work of the first C++ library used for prototyping in \cite{richoux2020automatic}. We decided to use some features of the Julia language to ease provisioning flexibility and broader features to ICNs. - -\subsection{The Julia language} -\label{subsec:julialang} - -The Julia language was introduced in~\cite{bezanson2017julia} and -purports to be a new take on \emph{mathematical programming}. Some -key features of the language, according to the official website, which -led us to consider it as an implementation vehicle: -\begin{description} -\item[Fast:] Julia was designed from the beginning for high - performance. Julia programs compile to efficient native code for - multiple platforms via LLVM~\cite{lattner2004llvm}. -\item[Dynamic:] It is dynamically typed, feels like a scripting - language, and has good support for interactive use. -\item[Reproducible:] Reproducible environments make it possible to - recreate the same Julia environment every time, across platforms, - with pre-built binaries. -\item[Composable:] It uses multiple dispatch as a paradigm, making it - easy to express many object-oriented and functional programming - patterns. -\item[General-purpose:] It provides metaprogramming, asynchronous I/O, - debugging, logging, profiling, a package manager, and more. One can - build entire Applications and Microservices in Julia. -\item[Open source:] It is an open source project with over 1,000 - contributors. It is made available under the MIT license and the - source code is available on GitHub. -\end{description} - -\subsection{Layers of operations} -\label{subsec:layers} - -A layer is defined by a non-empty collection of (possibly mutually exclusive) operations. Our basic ICN (for \efsp/\efop) is composed of four layers: \emph{transformation}, \emph{arithmetic} (exclusive), \emph{aggregation} (exclusive), and \emph{comparison} (exclusive). An illustration is given as Figure \ref{fig:model_icn}. The \texttt{Layer} structure stores these operations. - -\begin{lstlisting}[language = Julia] -struct Layer - functions::LittleDict{Symbol, Function} - exclusive::Bool -end -\end{lstlisting} - -The most complex layer is probably the \emph{transformation} layer. An operation (neuron) of this layer is defined over a vector of values and an optional parameter. As it is often simpler to define a transformation as a function over a specific index of the input vector, we provide meta-programming utility functions to generate vectorized methods: \texttt{lazy} and \texttt{lazy\_param}. - -\begin{lstlisting}[language = Julia] -# Transformation defined for a vector -tr_identity(x; param=nothing) = identity(x) - -# Transformation defined for the index of a vector -tr_count_eq(i, x; param=nothing) = - count(y -> x[i] == y, x) - 1 -tr_count_eq_param(i, x; param) = - count(y -> y == x[i] + param, x) - -# Generating vectorized versions -lazy(tr_count_eq) -lazy_param(tr_count_eq_param) -\end{lstlisting} - -When a concept is provided to an ICN, the user can provide an optional parameter input with the keyword argument \texttt{param}. A layer will be generated with or without the parametric operations (neurons) based on \texttt{param}'s value. Follow a shortened version of the transformation layer generator. - -\begin{lstlisting}[language = Julia] -function transformation_layer(param=false) - transformations = LittleDict{Symbol,Function}( - :identity => tr_identity, - :count_eq => tr_count_eq, - # ... - ) - if param - tr_param = LittleDict{Symbol, Function}( - :count_eq_param => tr_count_eq_param, - # ... - ) - transformations = LittleDict( - union(transformations, tr_param) - ) - end - return Layer(transformations, false) -end -\end{lstlisting} - -All methods required for the definition of additional layers are all available. An (unweighted) ICN is simply generated from a sequence of layers. After a learning phase using a genetic algorithm from \texttt{Evolutionary.jl}\footnote{\url{https://github.com/wildart/Evolutionary.jl}}, this ICN can output a composition in various forms. - -\subsection{Composition} -\label{subsec:composition} - -Once the ICN is weighted, we store its output as a composition with three forms. -A collection of \texttt{Symbol}s per layer of the ICN that allows the generation of code as a pre-process in any language, assuming the operations encoding in that language are available. \cnjl currently supports Julia, C, and C++. - -A composition also stores a Julia object of type \texttt{Function} to apply the composition in a dynamic fashion. - -\begin{lstlisting}[language = Julia] -struct Composition{F<:Function} - code::Dict{Symbol,String} - f::F - symbols::Vector{Vector{Symbol}} -end -\end{lstlisting} - -As mentioned above, an ICN outputs a composition, \ie{} a mathematical function composed of several basic operations. The \texttt{code} function returns the definition of a composition in either a mathematical or a programming language. From \texttt{v1} of \cnjl, \texttt{code} accepts \texttt{:maths} (default), \texttt{:Julia}, \texttt{:C}, \texttt{:Cpp} as values for the \texttt{lang} keyword argument. - -\begin{lstlisting}[language = Julia] -function code( - c::Composition, lang=:maths; - name="composition" -) - return get!( - c.code, lang, generate(c, name, Val(lang)) - ) -end -\end{lstlisting} - -\section{How to use \cnjl} -\label{sec:use} - -This section covers the essential steps to use ICN in a Julia environment. The actions required are few, which allow users to apply or export compositions effortlessly. - -\subsection{Installation and import} -\label{subsec:install} - -\cnjl will keep compatibility with the latest stable and LTS releases of Julia\footnote{Note that at the time of writing, Julia has just released \texttt{v1.7}. Compatibility with last LTS will start from the next LTS release.}. We recommend the users to install the latest version of Julia\footnote{\url{https://julialang.org/downloads/}} and to call it with \texttt{julia -t auto} which launch Julia with all available threads on the local machine. Installing \cnjl from the Julia REPL is as simple as: - -\begin{lstlisting}[language = Julia] -using Pkg -Pkg.update() -Pkg.add("CompositionalNetworks") -\end{lstlisting} - -Alternatively, one can install from the package REPL (simply press `]' in a Julia session) in a single command. - -\begin{lstlisting} -add CompositionalNetworks -\end{lstlisting} - -Finally, loading the package is done by calling: -\begin{lstlisting}[language = Julia] -using CompositionalNetworks -\end{lstlisting} - -Note that from Julia \texttt{v1.7}, calling \texttt{using} on an uninstalled package will prompt the user to install it. Hence, the last command is the only one strictly required. - -\subsection{Explore, learn, and compose} -\label{subsec:xlc} - -It is far from practical to apply the internals of \cnjl step-by-step. We provide a user-friendly sequence of higher-level actions that fits most of expected uses of this package: -\begin{itemize} - \item \emph{explore} a search space according to a collection of variables domains, a metric, and a concept with an optional parameter - \item \emph{learn} the weights of an ICN on that space according to the same metric - \item \emph{compose} the elementary operations according to the weights of the ICN -\end{itemize} - -The whole sequence can be executed through \texttt{explore\_learn\_compose}. That function accepts an increasingly large collection of (keyword) arguments: -\begin{itemize} - \item \texttt{domains}: domains of the variables that define the training space - \item \texttt{concept}: the concept of the targeted constraint - \item \texttt{param}: an optional parameter of the constraint - \item \texttt{search}: either \texttt{:flexible},\texttt{:partial} or \texttt{:complete} search. Flexible search will use \texttt{search\_limit} and \texttt{solutions\_limit} to determine if the search space needs to be partially or completely explored - \item \texttt{global\_iter}: number of learning iterations - \item \texttt{local\_iter}: number of generations in the underlying genetic algorithm - \item \texttt{metric}: the metric to measure the distance between a configuration and known solutions - \item \texttt{pop\_size}: size of the population in the genetic algorithm - \item \texttt{complete\_search\_limit}: used in conjunction with \texttt{solution\_limit} to determine if a flexible search is set to complete or partial - \item \texttt{solutions\_limit}: see above - \item \texttt{sampler}: optional sampler function for a collection of configurations - \item \texttt{configurations}: optional collection of configurations to use as a training set - \item \texttt{memoize}: if true, use a memoized version of the metric -\end{itemize} -Each of those actions is semi-automated through default parameters and machine learning over a large collection of benchmarks \cite{baffier2022interpretable}. - -\begin{lstlisting}[language = Julia] -function explore_learn_compose( - domains, - concept, - param=nothing; - global_iter=Threads.nthreads(), - local_iter=100, - metric=:hamming, - pop_size=400, - search=:flexible, - complete_search_limit=1000, - solutions_limit=100, - sampler=nothing, - configurations=explore( - domains, concept, param; - search, complete_search_limit, solutions_limit - ), - memoize=true, -) - dom_size = maximum(domain_size, domains) - solutions, non_sltns = configurations - return learn_compose( - solutions, - non_sltns, - dom_size, - param; - local_iter, - global_iter, - metric, - pop_size, - sampler, - memoize, - ) -end -\end{lstlisting} - -A long-term goal of \cnjl is to make the three first arguments optional too. We hope that such improvement will be used within \jc, for instance within the following more advanced examples. - -\subsection{Advanced examples} -\label{subsec:advanced} - -Large scale use of \cnjl is made within \jc and appears in: -\begin{itemize} - \item \cjl: the learning script can be found in \texttt{/src/learn.jl} and can be called as \texttt{learn\_from\_icn()}. - \item \icnbjl: an extensive collection of ICN benchmarks run on an HPC cluster. This package is not registered in the general registry of Julia packages. -\end{itemize} - -\section{Future challenges} -\label{sec:future} - -We envisage several directions for future improvement of ICN within \cnjl. Follows a non-comprehensive list of the most challenging features. - -\paragraph*{New operations in existing layers} As the experiments have shown in \cite{richoux2020automatic,baffier2022interpretable}, some concepts are too complex to be covered with the current set of operations. The most direct solutions is to provide a broader collection of elementary operations. - -\paragraph*{New layers} Applied to \efsp/\efop or not, it is likely that adding some layers of operation could cover a wider spectrum of combinatorial functions (with some cost for the interpretability and computation time). - -\paragraph*{Reinforcement learning} Some limitations in the ICN parametrization and metrics could be solved at runtime with dynamic learning. In the \jc context, this could occur at the solver execution. - -\paragraph*{Apply ICN to other fields and problems} Contributions and suggestions are more than welcome! - -\section{Problems, constraints, and compositions zoo} -\label{sec:zoo} - -The problems modelled, and the compositions extracted in this section are subject to future changes and improvements of the JuMP/JuCP packages. However, the keys ideas are presented here and examples will be updated accordingly within \jc in the future. We welcome GitHub issues and pull requests. - -\subsection{A few combinatorial models} -\label{subsec:models} - -At the moment, \cmjl hosts more than a dozen models. Along with \emph{Magic Square} introduced in Section \ref{subsec:example}, we present models for two other classical optimization problems: \emph{Golomb ruler} and \emph{minimum cut}. The choice was made to cover different type of constraints, with error functions learned from \cnjl. - -Note that a model for the minimum cut problem in a network requires a matrix (graph) as input. Additionally, we add the optional argument of the interdiction of some links in the cut, which lead to an intractable problem called \emph{Network Interdiction} \cite{baffier2016parametric}. - - -\begin{lstlisting}[language = Julia] -function mincut(graph, source, sink, interdiction) - m = JuMP.Model(CBLS.Optimizer) - n = size(graph, 1) - separator = n + 1 - - @variable(m, 0 <= X[1:separator] <= n, Int) - - @constraint(m, - [X[source], X[separator], X[sink]] in Ordered() - ) - @constraint(m, X in AllDifferent()) - - obj(x...) = o_mincut(graph, x...; interdiction) - @objective(m, Min, ScalarFunction(obj)) - - return m, X -end -\end{lstlisting} - -In contrast, an instance of the Golomb ruler problem does not require specific dataset. However, this problem exists as both satisfaction and optimization variants. - -\begin{lstlisting}[language = Julia] -function golomb(n, L) - m = JuMP.Model(CBLS.Optimizer) - - @variable(m, 0 <= X[1:n] <= L, Int) - - @constraint(m, X in AllDifferent()) - - # optional for output readability - @constraint(m, X in Ordered()) - - # No two pairs have the same length - for i in 1:(n - 1), j in (i + 1):n - for k in i:(n - 1), l in (k + 1):n - (i, j) < (k, l) || continue - @constraint(m, - [X[i], X[j], X[k], X[l]] in DistDifferent() - ) - end - end - - # Add objective - @objective(m, Min, ScalarFunction(maximum)) - - return m, X -end -\end{lstlisting} - -\subsection{Constraints and compositions} -\label{subsec:constraints} - -Along with the magic-square model in Section \ref{sec:introduction}, the models in this zoo use the following constraints: \texttt{:all\_different}, \texttt{:dist\_different}, \texttt{:linear}, and \texttt{:ordered}\footnote{The code provided here will be updated following the results of the benchmark in \cite{baffier2022interpretable}. In particular, for \texttt{:dist\_different} and \texttt{:linear}, the current code is a hand-written function.}.\newline - -The \emph{AllDifferent} constraint ensures that all the values of a given configuration are unique. This constraint is representative of Constraint Programming and is used in a large amount of models. - -\begin{lstlisting}[language = Julia] -function all_different(x; - X = zeros(length(x), 1), param=nothing, dom_size -) - tr_in(Tuple([tr_count_eq_left]), X, x, param) - for i in 1:length(x) - X[i,1] = ar_sum(@view X[i,:]) - end - return ag_count_positive(@view X[:,1]) |> ( - y -> co_identity( - y; param, dom_size, nvars=length(x) - ) - ) -end -\end{lstlisting} - -\emph{DistDifferent} is constraint ensuring that \(|x[1] - x[2]| \neq |x[3] - x[4]|\) for any vector $x$ of size $4$. - -\begin{lstlisting}[language = Julia] -function dist_different(x) - return abs(x[1] - x[2]) != abs(x[3] - x[4]) -end -\end{lstlisting} - -\emph{Linear} (also called \emph{Sum} or \emph{LinearSum} in the literature) Global ensures that the sum of the values of $x$ is equal to a given parameter $param$. Note that this version is a simplification of a linear sum of values with some coefficients. - -\begin{lstlisting}[language = Julia] -function linear(x; param, dom_size) - return abs(sum(x) - param) / dom_size -end -\end{lstlisting} - -\emph{Ordered} is a constraint ensuring that all the values of $x$ are ordered (here in a decreasing order). - -\begin{lstlisting}[language = Julia] -function ordered(x; - X = zeros(length(x), 1), param=nothing, dom_size -) - tr_in( - Tuple([tr_contiguous_vals_minus]), X, x, param - ) - for i in 1:length(x) - X[i,1] = ar_sum(@view X[i,:]) - end - return ag_count_positive(@view X[:,1]) |> ( - y -> co_identity( - y; param, dom_size, nvars=length(x) - ) - ) -end -\end{lstlisting} - -\section{Acknowledgements} -\label{sec:acknowledgements} - -We're grateful to Ricardo \textsc{Rosa} and Pranshu \textsc{Malik} for the logo of \jc presented as Figure \ref{fig:juliaconstraints}. - -\input{bib.tex} - -\end{document} - -% Inspired by the International Journal of Computer Applications template diff --git a/paper/paper.yml b/paper/paper.yml deleted file mode 100644 index 2fc138d..0000000 --- a/paper/paper.yml +++ /dev/null @@ -1,37 +0,0 @@ -title: "CompositionalNetworks.jl: a scaling glass-box neural network to learn combinatorial functions" -keywords: - - Julia Language - - Constraint Programming - - Local Search - - Metaheuristics - - Neural Network - - Metaprogramming - - Scalable Machine Learning - - Glass-Box Algorithm -authors: - - name: Jean-François \textsc{Baffier} - orcid: 0000-0002-8800-6356 - affiliation: 1 - - name: Khalil \textsc{Chrit} - orcid: 0000-0001-8845-7328 - affiliation: 2 - - name: Florian \textsc{Richoux} - orcid: 0000-0003-4693-379X - affiliation: "3,4" - - name: Pedro \textsc{Patinho} - orcid: 0000-0001-7906-6114 - affiliation: 2 - - name: Salvador \textsc{Abreu} - orcid: 0000-0002-1613-4631 - affiliation: 2 -affiliations: - - name: IIJ, Japan - index: 1 - - name: NOVA-LINCS, University of Évora, Portugal - index: 2 - - name: AIST, Japan - index: 3 - - name: JFLI, CNRS, Japan - index: 4 -date: 10 September 2021 -bibliography: ref.bib diff --git a/paper/prep.rb b/paper/prep.rb deleted file mode 100644 index 6da32f4..0000000 --- a/paper/prep.rb +++ /dev/null @@ -1,57 +0,0 @@ -# metadata generator for JuliaCon -# DO NOT EDIT - -require 'yaml' - -metadata = YAML.load_file('paper.yml') - -for k in ["title", "authors", "affiliations", "keywords", "bibliography"] - raise "Key #{k} not present in metadata" unless metadata.keys().include?(k) -end - -# ENV variables or default for issue/volume/year -issue = ENV["JLCON_ISSUE"] === nil ? 1 : ENV["JLCON_ISSUE"] -volume = ENV["JLCON_VOLUME"] === nil ? 1 : ENV["JLCON_VOLUME"] -year = ENV["JLCON_YEAR"] === nil ? 2021 : ENV["JLCON_YEAR"] -journal_name = "Proceedings of JuliaCon" # hard-coded for now - -open('header.tex', 'w') do |f| - f << "% **************GENERATED FILE, DO NOT EDIT**************\n\n" - f << "\\title{#{metadata["title"]}}\n\n" - for auth in metadata["authors"] - f << "\\author[#{auth["affiliation"]}]{#{auth["name"]}}\n" - end - for aff in metadata["affiliations"] - f << "\\affil[#{aff["index"]}]{#{aff["name"]}}\n" - end - f << "\n\\keywords{" - for i in 0...metadata["keywords"].length-1 - f << "#{metadata["keywords"][i]}, " - end - f << metadata["keywords"].last - f << "}\n\n" - - # hypersetup - f << "\\hypersetup{\n" - f << "pdftitle = {#{metadata["title"]}},\n" - f << "pdfsubject = {JuliaCon 2019 Proceedings},\n" - author_list = metadata['authors'].map { |a| a['name'] }.join(', ') - f << "pdfauthor = {#{author_list}},\n" - keyword_list = metadata['keywords'].join(', ') - f << "pdfkeywords = {#{keyword_list}},\n" - f << "}\n\n" -end - -open('journal_dat.tex', 'w') do |f| - f << "% **************GENERATED FILE, DO NOT EDIT**************\n\n" - f << "\\def\\@journalName{#{journal_name}}\n" - f << "\\def\\@volume{#{volume}}\n" - f << "\\def\\@issue{#{issue}}\n" - f << "\\def\\@year{#{year}}\n" -end - -open('bib.tex', 'w') do |f| - f << "% **************GENERATED FILE, DO NOT EDIT**************\n\n" - f << "\\bibliographystyle{juliacon}\n" - f << "\\bibliography{#{metadata["bibliography"]}}\n" -end diff --git a/paper/ref.bib b/paper/ref.bib deleted file mode 100644 index 46caf3d..0000000 --- a/paper/ref.bib +++ /dev/null @@ -1,186 +0,0 @@ -@article{bezanson2017julia, - title = {Julia: A fresh approach to numerical computing}, - author = {Bezanson, Jeff and Edelman, Alan and Karpinski, Stefan and Shah, Viral B}, - journal = {SIAM review}, - volume = {59}, - number = {1}, - pages = {65--98}, - year = {2017}, - publisher = {SIAM} -} - -@misc{richoux2020automatic, - primaryclass = {cs.AI}, - author = {Richoux, Florian and Baffier, Jean-François}, - eprint = {2002.09811}, - year = {2020}, - url = {https://arxiv.org/abs/2002.09811}, - archiveprefix = {arXiv}, - title = {Automatic Cost Function Learning with Interpretable Compositional Networks} -} - -@article{richoux2016ghost, - pages = {1-1}, - author = {Richoux, Florian and Uriarte, Alberto and Baffier, Jean-François}, - journal = {IEEE Transactions on Computational Intelligence and AI in Games}, - title = {GHOST: A Combinatorial Optimization Framework for RTS-related Problems}, - number = {99}, - doi = {10.1109/TCIAIG.2016.2573199}, - year = {2016}, - volume = {PP}, - annote = {\small GHOST is a competitive combinatorial optimization framework that a real-time strategy (RTS) AI developer can use to model and solve any problem encoded as a constraint satisfaction/optimization problem (CSP/COP).} -} - -@incollection{cooper2020guidedtour, - author = {Cooper, Martin and Givry, Simon and Schiex, Thomas}, - title = {Valued Constraint Satisfaction Problems}, - booktitle = {A Guided Tour of Artificial Intelligence Research}, - volume = {2}, - pages = {185-207}, - publisher = {Springer}, - year = {2020} -} - -@inproceedings{codognet2001adaptivesearch, - author = {Codognet, Philippe and Diaz, Daniel}, - title = {Yet Another Local Search Method for Constraint Solving}, - booktitle = {International Symposium on Stochastic Algorithms: Foundations and Applications ({SAGA} 2001)}, - pages = {73--90}, - publisher = {Springer}, - year = {2001} -} - -@article{stanley2007cppn, - author = {Stanley, Kenneth O.}, - title = {{Compositional Pattern Producing Networks: A Novel Abstraction of Development}}, - journal = {{Genetic Programming and Evolvable Machines}}, - volume = {8}, - number = {2}, - pages = {131--162}, - publisher = {Springer}, - year = {2007} -} - -@article{baffier2022interpretable, - author = {Baffier, Jean-François and Chrit, Khalil and Richoux, Florian and Patinho, Pedro and Abreu, Salvador}, - title = {Interpretable Composition Networks: A scaling glass-box neural network to learn combinatorial functions}, - journal = {IJCAI21-DSO Special issue of annals of mathematics and artificial intelligence on Data Science meets Optimization}, - volume = {2}, - year = {2022} -} - -@software{art_wilde_2021_5110647, - author = {Art Wilde and - Daniel Thiem and - Leo and - Abhinav Gupta and - Andrew Haselgrove and - Daniel Molina and - Honeypot95 and - matago and - Rogerluo and - Valentin Churavy}, - title = {Evolutionary.jl}, - month = jul, - year = 2021, - publisher = {Zenodo}, - version = {v0.10.0}, - doi = {10.5281/zenodo.5110647}, - url = {https://doi.org/10.5281/zenodo.5110647} -} - -@article{DunningHuchetteLubin2017, - author = {Iain Dunning and Joey Huchette and Miles Lubin}, - title = {JuMP: A Modeling Language for Mathematical Optimization}, - journal = {SIAM Review}, - volume = {59}, - number = {2}, - pages = {295-320}, - year = {2017}, - doi = {10.1137/15M1020575} -} - -@article{MathOptInterface-2021, - title = {MathOptInterface: a data structure for mathematical optimization problems}, - author = {Legat, Benoit and Dowson, Oscar and Garcia, Joaquim and Lubin, Miles}, - journal = {INFORMS Journal on Computing}, - year = {in press}, - publisher = {INFORMS} -} - -@incollection{DBLP:books/sp/18/CodognetMDA18, - author = {Philippe Codognet and - Danny Munera and - Daniel Diaz and - Salvador Abreu}, - editor = {Youssef Hamadi and - Lakhdar Sais}, - title = {Parallel Local Search}, - booktitle = {Handbook of Parallel Constraint Reasoning}, - pages = {381--417}, - publisher = {Springer}, - year = {2018}, - url = {https://doi.org/10.1007/978-3-319-63516-3\_10}, - doi = {10.1007/978-3-319-63516-3\_10}, - timestamp = {Sat, 19 Oct 2019 19:02:50 +0200}, - biburl = {https://dblp.org/rec/books/sp/18/CodognetMDA18.bib}, - bibsource = {dblp computer science bibliography, https://dblp.org} -} - -@article{chalumeau2021seapearl, - author = {Chalumeau, Félix and - Coulon, Ilan and - Cappart, Quentin and - Rousseau, Louis-Martin}, - title = {SeaPearl: {A} Constraint Programming Solver guided by Reinforcement - Learning}, - journal = {CoRR}, - volume = {abs/2102.09193}, - year = {2021}, - url = {https://arxiv.org/abs/2102.09193}, - archiveprefix = {arXiv}, - eprint = {2102.09193}, - timestamp = {Wed, 24 Feb 2021 15:42:45 +0100}, - biburl = {https://dblp.org/rec/journals/corr/abs-2102-09193.bib}, - bibsource = {dblp computer science bibliography, https://dblp.org} -} -@inproceedings{nethercote2007minizinc, - author = {Nethercote, Nicholas -and Stuckey, Peter J. -and Becket, Ralph -and Brand, Sebastian -and Duck, Gregory J. -and Tack, Guido}, - editor = {Bessi{\`e}re, Christian}, - title = {MiniZinc: Towards a Standard CP Modelling Language}, - booktitle = {Principles and Practice of Constraint Programming -- CP 2007}, - year = {2007}, - publisher = {Springer Berlin Heidelberg}, - address = {Berlin, Heidelberg}, - pages = {529--543}, - abstract = {There is no standard modelling language for constraint programming (CP) problems. Most solvers have their own modelling language. This makes it difficult for modellers to experiment with different solvers for a problem.}, - isbn = {978-3-540-74970-7} -} - -@inproceedings{lattner2004llvm, - title = {LLVM: A compilation framework for lifelong program analysis \& transformation}, - author = {Lattner, Chris and Adve, Vikram}, - booktitle = {International Symposium on Code Generation and Optimization, 2004. CGO 2004.}, - pages = {75--86}, - year = {2004}, - organization = {IEEE} -} -@article{baffier2016parametric, - pages = {20 - 36}, - author = {Baffier, Jean-François and Suppakitpaisarn, Vorapong and Hiraishi, Hidefumi and Imai, Hiroshi}, - journal = {Discrete Optimization}, - title = {Parametric multiroute flow and its application to multilink-attack network}, - doi = {10.1016/j.disopt.2016.05.002}, - keywords = {Graph and network algorithm, Approximation algorithm, Network flow, Network interdiction, Multiroute flow, Parametric optimization}, - issn = {1572-5286}, - note = {SI: ISCO 2014}, - year = {2016}, - url = {http://www.sciencedirect.com/science/article/pii/S1572528616300330}, - volume = {22}, - abstract = {We investigate variants of the max-flow problem in a network under k attacks. The network interdiction problem is to find the minimum max-flow value among (mk) networks that can be obtained by deleting each set of k links. The adaptive network flow problem is to find a flow of the network such that the flow value is maximum against any set of k links attack, when deleting the corresponding flow to those k links in the original flow. First, we prove that max-(k+1)-route flow is a (k+1)-approximation for both problems. Also, we develop a polynomial-time heuristic algorithm for both cases, called the iterative multiroute flow. Then in a second phase, we investigate properties of the function taking the real value h to the max h-route flow value, and apply the result to solve both of the problems. We show that the function is piecewise hyperbolic, and modify a standard parametric optimization technique to find this function. The running time of the algorithm is O(λT), when λ is a source–sink edge connectivity of our network and T the computation time of a max-flow algorithm. We show that for some instances, when h is optimally chosen, the max- h-route flow is an exact solution for both problems.} -} diff --git a/perf/allocs.jl b/perf/allocs.jl index 24bd41e..dcafcf9 100644 --- a/perf/allocs.jl +++ b/perf/allocs.jl @@ -24,5 +24,13 @@ using ConstraintDomains alloc() = explore_learn_compose(domains, allunique) # Actual call to PerfChecker - alloc_check(title, dependencies, targets, pre_alloc, alloc; path=@__DIR__, threads=10) + alloc_check( + title, + dependencies, + targets, + pre_alloc, + alloc; + path = @__DIR__, + threads = 10, + ) end diff --git a/perf/bench.jl b/perf/bench.jl index d34345f..5b37b3e 100644 --- a/perf/bench.jl +++ b/perf/bench.jl @@ -14,7 +14,8 @@ domains = fill(domain([1, 2, 3, 4]), 4) foreach(_ -> explore_learn_compose(domains, allunique), 1:10) # Code being benchmarked -t = @benchmark explore_learn_compose(domains, allunique) evals=1 samples=10 seconds=3600 +t = @benchmark explore_learn_compose(domains, allunique) evals = 1 samples = 10 seconds = + 3600 # Store the bench results -store_benchmark(t, target; path=@__DIR__) +store_benchmark(t, target; path = @__DIR__) diff --git a/src/CompositionalNetworks.jl b/src/CompositionalNetworks.jl index 869b65c..9242c00 100644 --- a/src/CompositionalNetworks.jl +++ b/src/CompositionalNetworks.jl @@ -39,9 +39,9 @@ export regularization export show_layers export symbols export transformation_layer -export weigths -export weigths! -export weigths_bias +export weights +export weights! +export weights_bias # Include utils include("utils.jl") diff --git a/src/composition.jl b/src/composition.jl index b1bac08..aa00907 100644 --- a/src/composition.jl +++ b/src/composition.jl @@ -24,7 +24,7 @@ end Access the code of a composition `c` in a given language `lang`. The name of the generated method is optional. """ -function code(c::Composition, lang=:maths; name="composition") +function code(c::Composition, lang = :maths; name = "composition") return get!(c.code, lang, generate(c, name, Val(lang))) end @@ -43,11 +43,11 @@ Output the composition as a layered collection of `Symbol`s. symbols(c::Composition) = c.symbols """ - compose(icn, weigths=nothing) -Return a function composed by some of the operations of a given ICN. Can be applied to any vector of variables. If `weigths` are given, will assign to `icn`. + compose(icn, weights=nothing) +Return a function composed by some of the operations of a given ICN. Can be applied to any vector of variables. If `weights` are given, will assign to `icn`. """ -function compose(icn::ICN, weigths::BitVector=BitVector()) - !isempty(weigths) && weigths!(icn, weigths) +function compose(icn::ICN, weights::BitVector = BitVector()) + !isempty(weights) && weights!(icn, weights) composition, symbols = _compose(icn) return Composition(composition, symbols) end @@ -69,10 +69,10 @@ function generate(c::Composition, name, ::Val{:Julia}) tr_length = length(symbs[1]) CN = "CompositionalNetworks." - tr = reduce_symbols(symbs[1], ", "; prefix=CN * "tr_") - ar = reduce_symbols(symbs[2], ", ", false; prefix=CN * "ar_") - ag = reduce_symbols(symbs[3], ", ", false; prefix=CN * "ag_") - co = reduce_symbols(symbs[4], ", ", false; prefix=CN * "co_") + tr = reduce_symbols(symbs[1], ", "; prefix = CN * "tr_") + ar = reduce_symbols(symbs[2], ", ", false; prefix = CN * "ar_") + ag = reduce_symbols(symbs[3], ", ", false; prefix = CN * "ag_") + co = reduce_symbols(symbs[4], ", ", false; prefix = CN * "co_") documentation = """\"\"\" $name(x; X = zeros(length(x), $tr_length), param=nothing, dom_size) @@ -91,7 +91,7 @@ function generate(c::Composition, name, ::Val{:Julia}) return $ag(@view X[:, 1]) |> (y -> $co(y; param, dom_size, nvars=length(x))) end """ - return documentation * format_text(output, BlueStyle(); pipe_to_function_call=false) + return documentation * format_text(output, BlueStyle(); pipe_to_function_call = false) end """ @@ -99,7 +99,7 @@ end Write the composition code in a given `language` into a file at `path`. """ -function composition_to_file!(c::Composition, path, name, language=:Julia) +function composition_to_file!(c::Composition, path, name, language = :Julia) output = code(c, language; name) write(path, output) return nothing diff --git a/src/icn.jl b/src/icn.jl index 4ee1eca..1831eb6 100644 --- a/src/icn.jl +++ b/src/icn.jl @@ -14,16 +14,16 @@ mutable struct ICN arithmetic::Layer aggregation::Layer comparison::Layer - weigths::BitVector + weights::BitVector function ICN(; - param=Vector{Symbol}(), - tr_layer=transformation_layer(param), - ar_layer=arithmetic_layer(), - ag_layer=aggregation_layer(), - co_layer=comparison_layer(param) + param = Vector{Symbol}(), + tr_layer = transformation_layer(param), + ar_layer = arithmetic_layer(), + ag_layer = aggregation_layer(), + co_layer = comparison_layer(param), ) - w = generate_weigths([tr_layer, ar_layer, ag_layer, co_layer]) + w = generate_weights([tr_layer, ar_layer, ag_layer, co_layer]) return new(tr_layer, ar_layer, ag_layer, co_layer, w) end end @@ -42,17 +42,17 @@ Base.length(icn::ICN) = sum(length, layers(icn)) """ nbits(icn) -Return the expected number of bits of a viable weigth of an ICN. +Return the expected number of bits of a viable weight of an ICN. """ nbits(icn) = mapreduce(l -> exclu(l) ? nbits_exclu(l) : length(l), +, layers(icn)) """ - weigths(icn) -Access the current set of weigths of an ICN. + weights(icn) +Access the current set of weights of an ICN. """ -weigths(icn) = icn.weigths +weights(icn) = icn.weights -function is_viable(icn::ICN, weigths) +function is_viable(icn::ICN, weights) _start = 0 _end = 0 @@ -60,35 +60,35 @@ function is_viable(icn::ICN, weigths) _start = _end + 1 _end += exclu(layer) ? nbits_exclu(layer) : length(layer) - w = @view weigths[_start:_end] + w = @view weights[_start:_end] !is_viable(layer, w) && return false end return true end -is_viable(icn::ICN) = is_viable(icn, weigths(icn)) +is_viable(icn::ICN) = is_viable(icn, weights(icn)) """ - weigths!(icn, weigths) -Set the weigths of an ICN with a `BitVector`. + weights!(icn, weights) +Set the weights of an ICN with a `BitVector`. """ -function weigths!(icn, weigths) - length(weigths) == nbits(icn) || @warn icn weigths nbits(icn) - @assert length(weigths) == nbits(icn) - return icn.weigths = weigths +function weights!(icn, weights) + length(weights) == nbits(icn) || @warn icn weights nbits(icn) + @assert length(weights) == nbits(icn) + return icn.weights = weights end """ show_layers(icn) -Return a formated string with each layers in the icn. +Return a formatted string with each layers in the icn. """ show_layers(icn) = map(show_layer, layers(icn)) -generate_weigths(icn::ICN) = generate_weigths(layers(icn)) +generate_weights(icn::ICN) = generate_weights(layers(icn)) """ regularization(icn) -Return the regularization value of an ICN weigths, which is proportional to the normalized number of operations selected in the icn layers. +Return the regularization value of an ICN weights, which is proportional to the normalized number of operations selected in the icn layers. """ function regularization(icn) Σmax = 0 @@ -100,14 +100,14 @@ function regularization(icn) _start = _end + 1 _end += exclu(layer) ? nbits_exclu(layer) : l if !exclu(layer) - Σop += selected_size(layer, @view weigths(icn)[_start:_end]) + Σop += selected_size(layer, @view weights(icn)[_start:_end]) Σmax += length(layer) end end return Σop / (Σmax + 1) end -max_icn_length(icn=ICN(; param=[:val])) = length(icn.transformation) +max_icn_length(icn = ICN(; param = [:val])) = length(icn.transformation) """ _compose(icn) @@ -116,8 +116,7 @@ Internal function called by `compose` and `show_composition`. function _compose(icn::ICN) !is_viable(icn) && ( return ( - (x; X=zeros(length(x), max_icn_length()), param=nothing, dom_size=0) -> - typemax(Float64) + (x; X = zeros(length(x), max_icn_length()), param = nothing, dom_size = 0) -> typemax(Float64) ), [] ) @@ -133,14 +132,14 @@ function _compose(icn::ICN) _end += exclu(layer) ? nbits_exclu(layer) : length(layer) if exclu(layer) - f_id = as_int(@view weigths(icn)[_start:_end]) + f_id = as_int(@view weights(icn)[_start:_end]) s = symbol(layer, f_id + 1) push!(funcs, [functions(layer)[s]]) push!(symbols, [s]) else layer_funcs = Vector{Function}() layer_symbs = Vector{Symbol}() - for (f_id, b) in enumerate(@view weigths(icn)[_start:_end]) + for (f_id, b) in enumerate(@view weights(icn)[_start:_end]) if b s = symbol(layer, f_id) push!(layer_funcs, functions(layer)[s]) @@ -152,11 +151,17 @@ function _compose(icn::ICN) end end - function composition(x; X=zeros(length(x), length(funcs[1])), param=nothing, dom_size) + function composition( + x; + X = zeros(length(x), length(funcs[1])), + param = nothing, + dom_size, + ) tr_in(Tuple(funcs[1]), X, x, param) - X[1:length(x), 1] .= 1:length(x) .|> (i -> funcs[2][1](@view X[i, 1:length(funcs[1])])) - return (y -> funcs[4][1](y; param, dom_size, nvars=length(x)))( - funcs[3][1](@view X[:, 1]) + X[1:length(x), 1] .= + 1:length(x) .|> (i -> funcs[2][1](@view X[i, 1:length(funcs[1])])) + return (y -> funcs[4][1](y; param, dom_size, nvars = length(x)))( + funcs[3][1](@view X[:, 1]), ) end diff --git a/src/layer.jl b/src/layer.jl index 223c2e3..d89f6e7 100644 --- a/src/layer.jl +++ b/src/layer.jl @@ -4,7 +4,7 @@ A structure to store a `LittleDict` of operations that can be selected during th """ struct Layer exclusive::Bool - functions::LittleDict{Symbol, Function} + functions::LittleDict{Symbol,Function} parameters::Vector{Symbol} end @@ -45,23 +45,23 @@ Return a string that contains the elements in a layer. show_layer(layer) = layer |> functions |> keys |> string """ - selected_size(layer, layer_weigths) -Return the number of operations selected by `layer_weigths` in `layer`. + selected_size(layer, layer_weights) +Return the number of operations selected by `layer_weights` in `layer`. """ -selected_size(layer, layer_weigths) = exclu(layer) ? 1 : sum(layer_weigths) +selected_size(layer, layer_weights) = exclu(layer) ? 1 : sum(layer_weights) """ is_viable(layer, w) is_viable(icn) is_viable(icn, w) -Assert if a pair of layer/icn and weigths compose a viable pattern. If no weigths are given with an icn, it will check the current internal value. +Assert if a pair of layer/icn and weights compose a viable pattern. If no weights are given with an icn, it will check the current internal value. """ is_viable(layer::Layer, w) = exclu(layer) ? as_int(w) < length(layer) : any(w) """ generate_inclusive_operations(predicate, bits) generate_exclusive_operation(max_op_number) -Generates the operations (weigths) of a layer with inclusive/exclusive operations. +Generates the operations (weights) of a layer with inclusive/exclusive operations. """ function generate_inclusive_operations(predicate, bits) ind = falses(bits) @@ -78,15 +78,16 @@ function generate_exclusive_operation(max_op_number) end """ - generate_weigths(layers) - generate_weigths(icn) -Generate the weigths of a collection of layers or of an ICN. + generate_weights(layers) + generate_weights(icn) +Generate the weights of a collection of layers or of an ICN. """ -function generate_weigths(layers) - bitvecs = map(l -> exclu(l) ? - generate_exclusive_operation(length(l)) : +function generate_weights(layers) + bitvecs = map( + l -> + exclu(l) ? generate_exclusive_operation(length(l)) : generate_inclusive_operations(any, length(l)), - layers + layers, ) return vcat(bitvecs...) end diff --git a/src/layers/aggregation.jl b/src/layers/aggregation.jl index 9f4887a..2d287ee 100644 --- a/src/layers/aggregation.jl +++ b/src/layers/aggregation.jl @@ -15,10 +15,8 @@ ag_count_positive(x) = count(y -> y > 0.0, x) Generate the layer of aggregations of the ICN. The operations are mutually exclusive, that is only one will be selected. """ function aggregation_layer() - aggregations = LittleDict{Symbol, Function}( - :sum => ag_sum, - :count_positive => ag_count_positive, - ) + aggregations = + LittleDict{Symbol,Function}(:sum => ag_sum, :count_positive => ag_count_positive) return Layer(true, aggregations, Vector{Symbol}()) end @@ -27,10 +25,7 @@ end @testitem "Aggregation Layer" tags = [:aggregation, :layer] begin CN = CompositionalNetworks - data = [ - [1, 5, 2, 4, 3] => 2, - [1, 2, 3, 2, 1] => 2, - ] + data = [[1, 5, 2, 4, 3] => 2, [1, 2, 3, 2, 1] => 2] @test CN.ag_sum(data[1].first) == 15 @test CN.ag_sum(data[2].first) == 9 diff --git a/src/layers/arithmetic.jl b/src/layers/arithmetic.jl index 3991cd2..76f42b0 100644 --- a/src/layers/arithmetic.jl +++ b/src/layers/arithmetic.jl @@ -15,10 +15,7 @@ ar_prod(x) = reduce((y, z) -> y .* z, x) Generate the layer of arithmetic operations of the ICN. The operations are mutually exclusive, that is only one will be selected. """ function arithmetic_layer() - arithmetics = LittleDict{Symbol, Function}( - :sum => ar_sum, - :prod => ar_prod, - ) + arithmetics = LittleDict{Symbol,Function}(:sum => ar_sum, :prod => ar_prod) return Layer(true, arithmetics, Vector{Symbol}()) end @@ -27,10 +24,7 @@ end @testitem "Arithmetic Layer" tags = [:arithmetic, :layer] begin CN = CompositionalNetworks - data = [ - [1, 5, 2, 4, 3] => 2, - [1, 2, 3, 2, 1] => 2, - ] + data = [[1, 5, 2, 4, 3] => 2, [1, 2, 3, 2, 1] => 2] @test CN.ar_sum(map(p -> p.first, data)) == [2, 7, 5, 6, 4] @test CN.ar_prod(map(p -> p.first, data)) == [1, 10, 6, 8, 3] diff --git a/src/layers/comparison.jl b/src/layers/comparison.jl index 2f30b13..4b70983 100644 --- a/src/layers/comparison.jl +++ b/src/layers/comparison.jl @@ -2,59 +2,61 @@ co_identity(x) Identity function. Already defined in Julia as `identity`, specialized for scalars in the `comparison` layer. """ -co_identity(x; param=nothing, dom_size=0, nvars=0) = identity(x) +co_identity(x; param = nothing, dom_size = 0, nvars = 0) = identity(x) """ co_abs_diff_val_param(x; param) Return the absolute difference between `x` and `param`. """ -co_abs_diff_val_param(x; param, dom_size=0, nvars=0) = abs(x - param) +co_abs_diff_val_param(x; param, dom_size = 0, nvars = 0) = abs(x - param) """ co_val_minus_param(x; param) Return the difference `x - param` if positive, `0.0` otherwise. """ -co_val_minus_param(x; param, dom_size=0, nvars=0) = max(0.0, x - param) +co_val_minus_param(x; param, dom_size = 0, nvars = 0) = max(0.0, x - param) """ co_param_minus_val(x; param) Return the difference `param - x` if positive, `0.0` otherwise. """ -co_param_minus_val(x; param, dom_size=0, nvars=0) = max(0.0, param - x) +co_param_minus_val(x; param, dom_size = 0, nvars = 0) = max(0.0, param - x) """ - co_euclidian_param(x; param, dom_size) -Compute an euclidian norm with domain size `dom_size`, weigthed by `param`, of a scalar. + co_euclidean_param(x; param, dom_size) +Compute an euclidean norm with domain size `dom_size`, weighted by `param`, of a scalar. """ -function co_euclidian_param(x; param, dom_size, nvars=0) +function co_euclidean_param(x; param, dom_size, nvars = 0) return x == param ? 0.0 : (1.0 + abs(x - param) / dom_size) end """ - co_euclidian(x; dom_size) -Compute an euclidian norm with domain size `dom_size` of a scalar. + co_euclidean(x; dom_size) +Compute an euclidean norm with domain size `dom_size` of a scalar. """ -function co_euclidian(x; param=nothing, dom_size, nvars=0) - return co_euclidian_param(x; param=0.0, dom_size=dom_size) +function co_euclidean(x; param = nothing, dom_size, nvars = 0) + return co_euclidean_param(x; param = 0.0, dom_size = dom_size) end """ co_abs_diff_val_vars(x; nvars) Return the absolute difference between `x` and the number of variables `nvars`. """ -co_abs_diff_val_vars(x; param=nothing, dom_size=0, nvars) = abs(x - nvars) +co_abs_diff_val_vars(x; param = nothing, dom_size = 0, nvars) = abs(x - nvars) """ co_val_minus_vars(x; nvars) Return the difference `x - nvars` if positive, `0.0` otherwise, where `nvars` denotes the numbers of variables. """ -co_val_minus_vars(x; param=nothing, dom_size=0, nvars) = co_val_minus_param(x; param=nvars) +co_val_minus_vars(x; param = nothing, dom_size = 0, nvars) = + co_val_minus_param(x; param = nvars) """ co_vars_minus_val(x; nvars) Return the difference `nvars - x` if positive, `0.0` otherwise, where `nvars` denotes the numbers of variables. """ -co_vars_minus_val(x; param=nothing, dom_size=0, nvars) = co_param_minus_val(x; param=nvars) +co_vars_minus_val(x; param = nothing, dom_size = 0, nvars) = + co_param_minus_val(x; param = nvars) # Parametric layers @@ -63,7 +65,7 @@ make_comparisons(param::Symbol) = make_comparisons(Val(param)) function make_comparisons(::Val{:none}) return LittleDict{Symbol,Function}( :identity => co_identity, - :euclidian => co_euclidian, + :euclidean => co_euclidean, :abs_diff_val_vars => co_abs_diff_val_vars, :val_minus_vars => co_val_minus_vars, :vars_minus_val => co_vars_minus_val, @@ -75,7 +77,7 @@ function make_comparisons(::Val{:val}) :abs_diff_val_param => co_abs_diff_val_param, :val_minus_param => co_val_minus_param, :param_minus_val => co_param_minus_val, - :euclidian_param => co_euclidian_param, + :euclidean_param => co_euclidean_param, ) end @@ -101,9 +103,7 @@ end data = [3 => (1, 5), 5 => (10, 5)] - funcs = [ - CN.co_identity => [3, 5], - ] + funcs = [CN.co_identity => [3, 5]] # test no param/vars for (f, results) in funcs @@ -120,7 +120,7 @@ end for (f, results) in funcs_param for (key, vals) in enumerate(data) - @test f(vals.first; param=vals.second[1]) == results[key] + @test f(vals.first; param = vals.second[1]) == results[key] end end @@ -132,27 +132,24 @@ end for (f, results) in funcs_vars for (key, vals) in enumerate(data) - @test f(vals.first, nvars=vals.second[2]) == results[key] + @test f(vals.first, nvars = vals.second[2]) == results[key] end end - funcs_param_dom = [ - CN.co_euclidian_param => [1.4, 2.0], - ] + funcs_param_dom = [CN.co_euclidean_param => [1.4, 2.0]] for (f, results) in funcs_param_dom for (key, vals) in enumerate(data) - @test f(vals.first, param=vals.second[1], dom_size=vals.second[2]) ≈ results[key] + @test f(vals.first, param = vals.second[1], dom_size = vals.second[2]) ≈ + results[key] end end - funcs_dom = [ - CN.co_euclidian => [1.6, 2.0], - ] + funcs_dom = [CN.co_euclidean => [1.6, 2.0]] for (f, results) in funcs_dom for (key, vals) in enumerate(data) - @test f(vals.first, dom_size=vals.second[2]) ≈ results[key] + @test f(vals.first, dom_size = vals.second[2]) ≈ results[key] end end diff --git a/src/layers/transformation.jl b/src/layers/transformation.jl index 2d4e837..3e008ce 100644 --- a/src/layers/transformation.jl +++ b/src/layers/transformation.jl @@ -161,7 +161,7 @@ tr_count_bounding_param(i, x; param) = count(y -> x[i] ≤ y ≤ x[i] + param, x # Generating vetorized versions lazy_param(tr_count_bounding_param) -# Val/param substractions +# Val/param subtractions """ tr_val_minus_param(i, x; param) @@ -186,7 +186,7 @@ tr_param_minus_val(i, x; param) = max(0, param - x[i]) # Generating vetorized versions lazy_param(tr_val_minus_param, tr_param_minus_val) -# Continuous values substraction +# Continuous values subtraction """ tr_contiguous_vals_minus(i, x) tr_contiguous_vals_minus(x) @@ -195,7 +195,8 @@ lazy_param(tr_val_minus_param, tr_param_minus_val) Return the difference `x[i] - x[i + 1]` if positive, `0.0` otherwise. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. """ -tr_contiguous_vals_minus(i, x; param=nothing) = length(x) == i ? 0 : tr_val_minus_param(i, x; param=x[i + 1]) +tr_contiguous_vals_minus(i, x; param = nothing) = + length(x) == i ? 0 : tr_val_minus_param(i, x; param = x[i+1]) """ tr_contiguous_vals_minus_rev(i, x) @@ -205,8 +206,8 @@ tr_contiguous_vals_minus(i, x; param=nothing) = length(x) == i ? 0 : tr_val_minu Return the difference `x[i + 1] - x[i]` if positive, `0.0` otherwise. Extended method to vector with sig `(x)` are generated. When `X` is provided, the result is computed without allocations. """ -function tr_contiguous_vals_minus_rev(i, x; param=nothing) - return length(x) == i ? 0 : tr_param_minus_val(i, x; param=x[i + 1]) +function tr_contiguous_vals_minus_rev(i, x; param = nothing) + return length(x) == i ? 0 : tr_param_minus_val(i, x; param = x[i+1]) end # Generating vetorized versions @@ -267,61 +268,22 @@ end @testitem "Arithmetic Layer" tags = [:arithmetic, :layer] begin CN = CompositionalNetworks - data = [ - [1, 5, 2, 4, 3] => 2, - [1, 2, 3, 2, 1] => 2, - ] + data = [[1, 5, 2, 4, 3] => 2, [1, 2, 3, 2, 1] => 2] # Test transformations without parameters funcs = Dict( - CN.tr_identity => [ - data[1].first, - data[2].first, - ], - CN.tr_count_eq => [ - [0, 0, 0, 0, 0], - [1, 1, 0, 1, 1], - ], - CN.tr_count_eq_right => [ - [0, 0, 0, 0, 0], - [1, 1, 0, 0, 0], - ], - CN.tr_count_eq_left => [ - [0, 0, 0, 0, 0], - [0, 0, 0, 1, 1], - ], - CN.tr_count_greater => [ - [4, 0, 3, 1, 2], - [3, 1, 0, 1, 3], - ], - CN.tr_count_lesser => [ - [0, 4, 1, 3, 2], - [0, 2, 4, 2, 0], - ], - CN.tr_count_g_left => [ - [0, 0, 1, 1, 2], - [0, 0, 0, 1, 3], - ], - CN.tr_count_l_left => [ - [0, 1, 1, 2, 2], - [0, 1, 2, 1, 0], - ], - CN.tr_count_g_right => [ - [4, 0, 2, 0, 0], - [3, 1, 0, 0, 0], - ], - CN.tr_count_l_right => [ - [0, 3, 0, 1, 0], - [0, 1, 2, 1, 0], - ], - CN.tr_contiguous_vals_minus => [ - [0, 3, 0, 1, 0], - [0, 0, 1, 1, 0], - ], - CN.tr_contiguous_vals_minus_rev => [ - [4, 0, 2, 0, 0], - [1, 1, 0, 0, 0], - ], + CN.tr_identity => [data[1].first, data[2].first], + CN.tr_count_eq => [[0, 0, 0, 0, 0], [1, 1, 0, 1, 1]], + CN.tr_count_eq_right => [[0, 0, 0, 0, 0], [1, 1, 0, 0, 0]], + CN.tr_count_eq_left => [[0, 0, 0, 0, 0], [0, 0, 0, 1, 1]], + CN.tr_count_greater => [[4, 0, 3, 1, 2], [3, 1, 0, 1, 3]], + CN.tr_count_lesser => [[0, 4, 1, 3, 2], [0, 2, 4, 2, 0]], + CN.tr_count_g_left => [[0, 0, 1, 1, 2], [0, 0, 0, 1, 3]], + CN.tr_count_l_left => [[0, 1, 1, 2, 2], [0, 1, 2, 1, 0]], + CN.tr_count_g_right => [[4, 0, 2, 0, 0], [3, 1, 0, 0, 0]], + CN.tr_count_l_right => [[0, 3, 0, 1, 0], [0, 1, 2, 1, 0]], + CN.tr_contiguous_vals_minus => [[0, 3, 0, 1, 0], [0, 0, 1, 1, 0]], + CN.tr_contiguous_vals_minus_rev => [[4, 0, 2, 0, 0], [1, 1, 0, 0, 0]], ) for (f, results) in funcs @@ -334,37 +296,19 @@ end # Test transformations with parameter funcs_param = Dict( - CN.tr_count_eq_param => [ - [1, 0, 1, 0, 1], - [1, 0, 0, 0, 1], - ], - CN.tr_count_l_param => [ - [2, 5, 3, 5, 4], - [4, 5, 5, 5, 4], - ], - CN.tr_count_g_param => [ - [2, 0, 1, 0, 0], - [0, 0, 0, 0, 0], - ], - CN.tr_count_bounding_param => [ - [3, 1, 3, 2, 3], - [5, 3, 1, 3, 5], - ], - CN.tr_val_minus_param => [ - [0, 3, 0, 2, 1], - [0, 0, 1, 0, 0], - ], - CN.tr_param_minus_val => [ - [1, 0, 0, 0, 0], - [1, 0, 0, 0, 1], - ], + CN.tr_count_eq_param => [[1, 0, 1, 0, 1], [1, 0, 0, 0, 1]], + CN.tr_count_l_param => [[2, 5, 3, 5, 4], [4, 5, 5, 5, 4]], + CN.tr_count_g_param => [[2, 0, 1, 0, 0], [0, 0, 0, 0, 0]], + CN.tr_count_bounding_param => [[3, 1, 3, 2, 3], [5, 3, 1, 3, 5]], + CN.tr_val_minus_param => [[0, 3, 0, 2, 1], [0, 0, 1, 0, 0]], + CN.tr_param_minus_val => [[1, 0, 0, 0, 0], [1, 0, 0, 0, 1]], ) for (f, results) in funcs_param @info f for (key, vals) in enumerate(data) - @test f(vals.first; param=vals.second) == results[key] - foreach(i -> f(i, vals.first; param=vals.second), vals.first) + @test f(vals.first; param = vals.second) == results[key] + foreach(i -> f(i, vals.first; param = vals.second), vals.first) end end diff --git a/src/learn.jl b/src/learn.jl index 71a8dbf..6a71559 100644 --- a/src/learn.jl +++ b/src/learn.jl @@ -15,25 +15,18 @@ function learn_compose( solutions, non_sltns, dom_size; - metric=:hamming, + metric = :hamming, optimizer, - X_test=nothing, - parameters... + X_test = nothing, + parameters..., ) icn = ICN(; parameters...) - _, weigths = optimize!( - icn, - solutions, - non_sltns, - dom_size, - metric, - optimizer; - parameters... - ) + _, weights = + optimize!(icn, solutions, non_sltns, dom_size, metric, optimizer; parameters...) compositions = Dictionary{Composition,Int}() - for (bv, occurences) in pairs(weigths) - set!(compositions, compose(deepcopy(icn), bv), occurences) + for (bv, occurrences) in pairs(weights) + set!(compositions, compose(deepcopy(icn), bv), occurrences) end return compose(icn), icn, compositions @@ -58,11 +51,11 @@ Explore a search space, learn a composition from an ICN, and compose an error fu function explore_learn_compose( domains, concept; - configurations=nothing, - metric=:hamming, + configurations = nothing, + metric = :hamming, optimizer, - X_test=nothing, - parameters... + X_test = nothing, + parameters..., ) if isnothing(configurations) configurations = explore(domains, concept; parameters...) @@ -77,7 +70,7 @@ function explore_learn_compose( metric, optimizer, X_test, - parameters... + parameters..., ) end @@ -92,7 +85,7 @@ Explore, learn and compose a function and write it to a file. - `path`: path of the output file # Keywords arguments: - `domains`: domains that defines the search space -- `param`: an optional paramater of the constraint +- `param`: an optional parameter of the constraint - `language`: the language to export to, default to `:julia` - `search`: either `:partial` or `:complete` search - `global_iter`: number of learning iteration @@ -104,13 +97,13 @@ function compose_to_file!( concept, name, path; - configurations=nothing, + configurations = nothing, domains, - language=:Julia, - metric=:hamming, + language = :Julia, + metric = :hamming, optimizer, - X_test=nothing, - parameters... + X_test = nothing, + parameters..., ) if isnothing(configurations) configurations = explore(domains, concept; parameters...) @@ -123,7 +116,7 @@ function compose_to_file!( metric, optimizer, X_test, - parameters... + parameters..., ) composition_to_file!(compo, path, name, language) return icn diff --git a/src/metrics.jl b/src/metrics.jl index 5b38b07..992b323 100644 --- a/src/metrics.jl +++ b/src/metrics.jl @@ -2,7 +2,7 @@ hamming(x, X) Compute the hamming distance of `x` over a collection of solutions `X`, i.e. the minimal number of variables to switch in `x`to reach a solution. """ -hamming(x, X) = mapreduce(y -> Distances.hamming(x,y), min, X) +hamming(x, X) = mapreduce(y -> Distances.hamming(x, y), min, X) """ minkowski(x, X, p) @@ -15,7 +15,7 @@ minkowski(x, X, p) = mapreduce(Distances.minkowski(x, y, p), min, X) manhattan(x, X) = mapreduce(y -> Distances.cityblock(x, y), min, X) """ - weigths_bias(x) + weights_bias(x) A metric that bias `x` towards operations with a lower bit. Do not affect the main metric. """ -weigths_bias(x) = sum(p -> p[1] * log2(1. + p[2]), enumerate(x)) / length(x)^4 +weights_bias(x) = sum(p -> p[1] * log2(1.0 + p[2]), enumerate(x)) / length(x)^4 diff --git a/src/utils.jl b/src/utils.jl index 60f9688..6251684 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -3,10 +3,20 @@ Return an anonymous function that applies `f` to all elements of `x` and store the result in `X`, with a parameter `param` (which is set to `nothing` for function with no parameter). """ function map_tr!(f, x, X, p) - return ((g, y, Y; param) -> map!(i -> g(i, y; param), Y, 1:length(y)))(f, x, X; param=p) + return ((g, y, Y; param) -> map!(i -> g(i, y; param), Y, 1:length(y)))( + f, + x, + X; + param = p, + ) end function map_tr!(f, x, X) - return ((g, y, Y; param) -> map!(i -> g(i, y), Y, 1:length(y)))(f, x, X; param=nothing) + return ((g, y, Y; param) -> map!(i -> g(i, y), Y, 1:length(y)))( + f, + x, + X; + param = nothing, + ) end """ @@ -15,14 +25,10 @@ Generate methods extended to a vector instead of one of its components. A functi """ function lazy(funcs::Function...) for f in Iterators.map(Symbol, funcs) - eval( - :( - function $f(x::V, X; param=nothing) where {V<:AbstractVector} - return map_tr!($f, x, X) - end - ), - ) - eval(:($f(x; param=nothing) = $f(x, similar(x); param))) + eval(:(function $f(x::V, X; param = nothing) where {V<:AbstractVector} + return map_tr!($f, x, X) + end)) + eval(:($f(x; param = nothing) = $f(x, similar(x); param))) end return nothing end @@ -43,7 +49,7 @@ end as_bitvector(n::Int, max_n::Int = n) Convert an Int to a BitVector of minimal size (relatively to `max_n`). """ -function as_bitvector(n::Int, max_n::Int=n) +function as_bitvector(n::Int, max_n::Int = n) nm1 = n - 1 v = falses(ceil(Int, log2(max_n))) i = 0 @@ -72,7 +78,7 @@ end reduce_symbols(symbols, sep) Produce a formatted string that separates the symbols by `sep`. Used internally for `show_composition`. """ -function reduce_symbols(symbols, sep, parenthesis=true; prefix="") +function reduce_symbols(symbols, sep, parenthesis = true; prefix = "") str = reduce((x, y) -> "$y$sep$x", map(s -> "$prefix$s", symbols)) return parenthesis ? "[$str]" : str end @@ -83,7 +89,7 @@ end Application of an operation from the transformation layer. Used to generate more efficient code for all compositions. """ @unroll function tr_in(tr, X, x, param) - @unroll for i in 1:length(tr) + @unroll for i = 1:length(tr) tr[i](x, @view(X[:, i]); param) end end diff --git a/test/Aqua.jl b/test/Aqua.jl new file mode 100644 index 0000000..4a12a23 --- /dev/null +++ b/test/Aqua.jl @@ -0,0 +1,27 @@ +@testset "Aqua.jl" begin + import Aqua + import CompositionalNetworks + + # TODO: Fix the broken tests and remove the `broken = true` flag + Aqua.test_all( + CompositionalNetworks; + ambiguities = (broken = true,), + deps_compat = false, + piracies = (broken = false,), + ) + + @testset "Ambiguities: CompositionalNetworks" begin + # Aqua.test_ambiguities(CompositionalNetworks;) + end + + @testset "Piracies: CompositionalNetworks" begin + Aqua.test_piracies(CompositionalNetworks;) + end + + @testset "Dependencies compatibility (no extras)" begin + Aqua.test_deps_compat( + CompositionalNetworks; + check_extras = false, # ignore = [:Random] + ) + end +end diff --git a/test/Project.toml b/test/Project.toml deleted file mode 100644 index 1600931..0000000 --- a/test/Project.toml +++ /dev/null @@ -1,10 +0,0 @@ -[deps] -CompositionalNetworks = "4b67e4b5-442d-4ef5-b760-3f5df3a57537" -ConstraintDomains = "5800fd60-8556-4464-8d61-84ebf7a0bedb" -Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" -Evolutionary = "86b6b26d-c046-49b6-aa0b-5f0f74682bd6" -Memoization = "6fafb56a-5788-4b4e-91ca-c0cea6611c73" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a" -TestItems = "1c621080-faea-4a02-84b6-bbd5e436b8fe" -ThreadPools = "b189fb0b-2eb5-4ed4-bc0c-d34c51242431" diff --git a/test/TestItemRunner.jl b/test/TestItemRunner.jl new file mode 100644 index 0000000..cf86c5a --- /dev/null +++ b/test/TestItemRunner.jl @@ -0,0 +1,3 @@ +@testset "TestItemRunner" begin + @run_package_tests +end diff --git a/test/genetic.jl b/test/genetic.jl index b5f9e78..2b1f22c 100644 --- a/test/genetic.jl +++ b/test/genetic.jl @@ -1,6 +1,6 @@ """ generate_population(icn, pop_size -Generate a pôpulation of weigths (individuals) for the genetic algorithm weigthing `icn`. +Generate a pôpulation of weights (individuals) for the genetic algorithm weighting `icn`. """ function generate_population(icn, pop_size) population = Vector{BitVector}() @@ -10,7 +10,7 @@ end """ _optimize!(icn, X, X_sols; metric = hamming, pop_size = 200) -Optimize and set the weigths of an ICN with a given set of configuration `X` and solutions `X_sols`. +Optimize and set the weights of an ICN with a given set of configuration `X` and solutions `X_sols`. """ function _optimize!( icn, @@ -20,9 +20,9 @@ function _optimize!( metric, pop_size, iterations; - samples=nothing, - memoize=false, - parameters... + samples = nothing, + memoize = false, + parameters..., ) inplace = zeros(dom_size, max_icn_length()) _non_sltns = isnothing(samples) ? non_sltns : rand(non_sltns, samples) @@ -32,31 +32,32 @@ function _optimize!( f = composition(compo) S = Iterators.flatten((solutions, _non_sltns)) σ = sum( - x -> abs(f(x; X=inplace, dom_size, parameters...) - metric(x, solutions)), S + x -> abs(f(x; X = inplace, dom_size, parameters...) - metric(x, solutions)), + S, ) - return σ + regularization(icn) + weigths_bias(w) + return σ + regularization(icn) + weights_bias(w) end _fitness = memoize ? (@memoize Dict memoize_fitness(w) = fitness(w)) : fitness _icn_ga = GA(; - populationSize=pop_size, - crossoverRate=0.8, - epsilon=0.05, - selection=tournament(2), - crossover=SPX, - mutation=flip, - mutationRate=1.0 + populationSize = pop_size, + crossoverRate = 0.8, + epsilon = 0.05, + selection = tournament(2), + crossover = SPX, + mutation = flip, + mutationRate = 1.0, ) pop = generate_population(icn, pop_size) r = Evolutionary.optimize(_fitness, pop, _icn_ga, Evolutionary.Options(; iterations)) - return weigths!(icn, Evolutionary.minimizer(r)) + return weights!(icn, Evolutionary.minimizer(r)) end """ optimize!(icn, X, X_sols, global_iter, local_iter; metric=hamming, popSize=100) -Optimize and set the weigths of an ICN with a given set of configuration `X` and solutions `X_sols`. The best weigths among `global_iter` will be set. +Optimize and set the weights of an ICN with a given set of configuration `X` and solutions `X_sols`. The best weights among `global_iter` will be set. """ function optimize!( icn, @@ -67,17 +68,17 @@ function optimize!( dom_size, metric, pop_size; - sampler=nothing, - memoize=false, - parameters... + sampler = nothing, + memoize = false, + parameters..., ) results = Dictionary{BitVector,Int}() aux_results = Vector{BitVector}(undef, global_iter) nt = Base.Threads.nthreads() - @info """Starting optimization of weigths$(nt > 1 ? " (multithreaded)" : "")""" + @info """Starting optimization of weights$(nt > 1 ? " (multithreaded)" : "")""" samples = isnothing(sampler) ? nothing : sampler(length(solutions) + length(non_sltns)) - @qthreads for i in 1:global_iter + @qthreads for i = 1:global_iter @info "Iteration $i" aux_icn = deepcopy(icn) _optimize!( @@ -90,13 +91,13 @@ function optimize!( iter; samples, memoize, - parameters... + parameters..., ) - aux_results[i] = weigths(aux_icn) + aux_results[i] = weights(aux_icn) end foreach(bv -> incsert!(results, bv), aux_results) best = rand(findall(x -> x == maximum(results), results)) - weigths!(icn, best) + weights!(icn, best) return best, results end @@ -109,18 +110,23 @@ struct GeneticOptimizer <: AbstractOptimizer end function GeneticOptimizer(; - global_iter=Threads.nthreads(), - local_iter=64, - memoize=false, - pop_size=64, - sampler=nothing + global_iter = Threads.nthreads(), + local_iter = 64, + memoize = false, + pop_size = 64, + sampler = nothing, ) return GeneticOptimizer(global_iter, local_iter, memoize, pop_size, sampler) end -function CN.optimize!( - icn, solutions, non_sltns, dom_size, metric, optimizer::GeneticOptimizer; - parameters... +function CompositionalNetworks.optimize!( + icn, + solutions, + non_sltns, + dom_size, + metric, + optimizer::GeneticOptimizer; + parameters..., ) return optimize!( icn, @@ -133,6 +139,6 @@ function CN.optimize!( optimizer.pop_size; optimizer.sampler, optimizer.memoize, - parameters... + parameters..., ) end diff --git a/test/icn.jl b/test/icn.jl index a66dfac..e992037 100644 --- a/test/icn.jl +++ b/test/icn.jl @@ -1,27 +1,45 @@ -# # Test with manually weighted ICN -icn = ICN(param=[:val]) -@test max_icn_length() == 18 -show_layers(icn) +@testset "ICNs" begin + using CompositionalNetworks + using ConstraintDomains + using Dictionaries + using Evolutionary + using Memoization + using Test + using ThreadPools -icn.weigths = vcat(trues(18), falses(6)) -@test CN.is_viable(icn) -@test length(icn) == 31 + import CompositionalNetworks: AbstractOptimizer -compo = compose(icn) -@test code(compo; name = "test_composition") == "test_composition = identity ∘ sum ∘ sum ∘ [param_minus_val, val_minus_param" * - ", count_bounding_param, count_g_param, count_l_param, count_eq_param," * - " contiguous_vals_minus_rev, contiguous_vals_minus, count_l_right, count_g_right" * ", count_l_left, count_g_left, count_lesser, count_greater, count_eq_right, " * "count_eq_left, count_eq, identity]" + include("genetic.jl") -v = [1,2,4,3] -@test composition(compo)(v; param=2, dom_size=4) == 67 + # # Test with manually weighted ICN + icn = ICN(param = [:val]) + @test max_icn_length() == 18 + show_layers(icn) -CN.generate_weigths(icn) + icn.weights = vcat(trues(18), falses(6)) + @test CompositionalNetworks.is_viable(icn) + @test length(icn) == 31 -## Test GA and exploration -domains = [domain([1,2,3,4]) for i in 1:4] -compo, _ = explore_learn_compose(domains, allunique; optimizer = GeneticOptimizer()) -@test composition(compo)([1,2,3,3], dom_size = 4) > 0.0 + compo = compose(icn) + @test code(compo; name = "test_composition") == + "test_composition = identity ∘ sum ∘ sum ∘ [param_minus_val, val_minus_param" * + ", count_bounding_param, count_g_param, count_l_param, count_eq_param," * + " contiguous_vals_minus_rev, contiguous_vals_minus, count_l_right, count_g_right" * + ", count_l_left, count_g_left, count_lesser, count_greater, count_eq_right, " * + "count_eq_left, count_eq, identity]" -## Test export to file -composition_to_file!(compo, "test_dummy.jl", "all_different") -rm("test_dummy.jl"; force = true) + v = [1, 2, 4, 3] + @test composition(compo)(v; param = 2, dom_size = 4) == 67 + + CompositionalNetworks.generate_weights(icn) + + ## Test GA and exploration + domains = [domain([1, 2, 3, 4]) for i = 1:4] + compo, _ = explore_learn_compose(domains, allunique; optimizer = GeneticOptimizer()) + @test composition(compo)([1, 2, 3, 3], dom_size = 4) > 0.0 + + ## Test export to file + composition_to_file!(compo, "test_dummy.jl", "all_different") + rm("test_dummy.jl"; force = true) + +end diff --git a/test/runtests.jl b/test/runtests.jl index ff7f373..8c2c27c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,21 +1,9 @@ +using Test using TestItemRunner using TestItems -@run_package_tests - -@testitem "ICN: genetic algo" tags = [:icn, :genetic] default_imports=false begin - using CompositionalNetworks - using ConstraintDomains - using Dictionaries - using Evolutionary - using Memoization - using Test - using ThreadPools - - CN = CompositionalNetworks - - import CompositionalNetworks: AbstractOptimizer - - include("genetic.jl") +@testset "Package tests: CompositionalNetworks" begin + include("Aqua.jl") + include("TestItemRunner.jl") include("icn.jl") end