Skip to content

Commit

Permalink
ICN and doc update (prepare the beta release) (#9)
Browse files Browse the repository at this point in the history
* Deleted Manifest from git and added it to .gitignore

* Script to compute error from ICN in /learn

* Added learning script and results

* temp save

* temp save

* Moved learning folder. Updated param and dom_size kwarg

* Added new icn results and learning script

* improved doc

* Correct wrong meta info

* Updated learned errors
  • Loading branch information
Azzaare authored Jan 15, 2021
1 parent 3ea3626 commit 427e2f9
Show file tree
Hide file tree
Showing 18 changed files with 152 additions and 36 deletions.
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
name = "Constraints"
uuid = "30f324ab-b02d-43f0-b619-e131c61659f7"
authors = ["Jean-François Baffier"]
version = "0.1.5"
version = "0.1.6"

[deps]
CompositionalNetworks = "4b67e4b5-442d-4ef5-b760-3f5df3a57537"
ConstraintDomains = "5800fd60-8556-4464-8d61-84ebf7a0bedb"
Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4"

[compat]
ConstraintDomains = "0.1.1"
CompositionalNetworks = "0.1.2"
Dictionaries = "0.3.6"
CompositionalNetworks = "0.1.3"
ConstraintDomains = "0.1.2"
Dictionaries = "0.3"
julia = "1.5, 1.6"

[extras]
Expand Down
2 changes: 2 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[deps]
CompositionalNetworks = "4b67e4b5-442d-4ef5-b760-3f5df3a57537"
ConstraintDomains = "5800fd60-8556-4464-8d61-84ebf7a0bedb"
Constraints = "30f324ab-b02d-43f0-b619-e131c61659f7"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
15 changes: 12 additions & 3 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Constraints
using CompositionalNetworks
using ConstraintDomains
using Documenter

makedocs(;
modules=[Constraints],
modules=[Constraints, ConstraintDomains, CompositionalNetworks],
authors="Jean-François Baffier",
repo="https://github.com/JuliaConstraints/Constraints.jl/blob/{commit}{path}#L{line}",
sitename="Constraints.jl",
Expand All @@ -13,8 +15,15 @@ makedocs(;
),
pages=[
"Home" => "index.md",
"Library" => "library.md",
"Contributing" => "contributing.md",
"Learning (ICN)" => "learning.md",
"Dependencies" => [
"ConstraintDomains.jl" => "domain.md",
"CompositionalNetworks.jl" => "icn.md",
],
"Library" => [
"Public" => "public.md",
"Internal" => "internal.md"
],
],
)

Expand Down
7 changes: 7 additions & 0 deletions docs/src/domain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ConstraintDomains.jl

Currently only discrete domains are supported using the following function.

```@docs
ConstraintDomains.domain
```
58 changes: 58 additions & 0 deletions docs/src/icn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# CompositionalNetworks.jl

```@contents
Pages = ["public.md"]
Depth = 5
```

`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.

## Public interface

```@autodocs
Modules = [CompositionalNetworks]
Private = false
```
40 changes: 39 additions & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,43 @@
CurrentModule = Constraints
```

# Constraints for JuliaConstraints front packages
# Constraints.jl

A back-end pacage for JuliaConstraints front packages, such as `LocalSearchSolvers.jl`.

It provides the following features:
- A dictionary to store usual constraint: `usual_contraint`, which contains the following entries
- `:all_different`
- `:dist_different`
- `:eq`, `:all_equal`, `:all_equal_param`
- `:ordered`
- `:always_true` (mainly for testing default `Constraint()` constructor)
- For each constraint `c`, the following properties
- arguments length
- concept (predicate the variables compliance with `c`)
- error (a function that evaluate how much `c` is violated)
- parameters length
- known symmetries of `c`
- A learning function using `CompositionalNetworks.jl`. If no error function is given when instanciating `c`, it will check the existence of a composition related to `c` and set the error to it.

Follow the list of the constraints currently stored in `usual_constraint`. Note that if the constraint is named `_my_constraint`, it can be accessed as `usual_contraint[:my_constraint]`.

```@docs
Constraints._all_different
Constraints._all_equal
Constraints._all_equal_param
Constraints._dist_different
Constraints._eq
Constraints._ordered
```

## Contributing

Contributions to this package are more than welcome and can be arbitrarily, and not exhaustively, split as follows:
- Adding new constraints and symmetries
- Adding new ICNs to learn error of existing constraints
- Creating other compositional networks which target other kind of constraints
- 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.
11 changes: 11 additions & 0 deletions docs/src/internal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Internal

```@contents
Pages = ["internal.md"]
Depth = 5
```

```@autodocs
Modules = [Constraints]
Public = false
```
File renamed without changes.
8 changes: 0 additions & 8 deletions docs/src/library.md

This file was deleted.

11 changes: 11 additions & 0 deletions docs/src/public.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Public

```@contents
Pages = ["public.md"]
Depth = 5
```

```@autodocs
Modules = [Constraints]
Private = false
```
2 changes: 1 addition & 1 deletion src/Constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CompositionalNetworks: hamming, explore_learn_compose, compose_to_file!
import ConstraintDomains: domain

# Exports
export Constraint, usual_constraints
export Constraint, usual_constraints, usual_symmetries
export args_length, concept, error_f, params_length, symmetries

# Includes internals
Expand Down
2 changes: 1 addition & 1 deletion src/compositions/_icn_all_different.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
function _icn_all_different(x; param=nothing, dom_size)
fill(x, 1) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_count_eq_left]) |> CompositionalNetworks._ar_prod |> CompositionalNetworks._ag_count_positive |> (y -> CompositionalNetworks._co_identity(y; param=param, dom_size=dom_size, nvars=length(x)))
fill(x, 1) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_count_eq_right]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_count_positive |> (y -> CompositionalNetworks._co_identity(y; param=param, dom_size=dom_size, nvars=length(x)))
end
2 changes: 1 addition & 1 deletion src/compositions/_icn_all_equal.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
function _icn_all_equal(x; param=nothing, dom_size)
fill(x, 1) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_identity]) |> CompositionalNetworks._ar_prod |> CompositionalNetworks._ag_count_positive |> (y -> CompositionalNetworks._co_euclidian(y; param=param, dom_size=dom_size, nvars=length(x)))
fill(x, 1) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_identity]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_count_positive |> (y -> CompositionalNetworks._co_euclidian(y; param=param, dom_size=dom_size, nvars=length(x)))
end
2 changes: 1 addition & 1 deletion src/compositions/_icn_all_equal_param.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
function _icn_all_equal_param(x; param=nothing, dom_size)
fill(x, 1) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_count_g_param]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_sum |> (y -> CompositionalNetworks._co_vars_minus_val(y; param=param, dom_size=dom_size, nvars=length(x)))
fill(x, 5) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_val_minus_param, CompositionalNetworks._tr_count_g_param, CompositionalNetworks._tr_count_l_right, CompositionalNetworks._tr_count_lesser, CompositionalNetworks._tr_count_eq]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_count_positive |> (y -> CompositionalNetworks._co_identity(y; param=param, dom_size=dom_size, nvars=length(x)))
end
2 changes: 1 addition & 1 deletion src/compositions/_icn_dist_different.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
function _icn_dist_different(x; param=nothing, dom_size)
fill(x, 4) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_count_l_right, CompositionalNetworks._tr_count_lesser, CompositionalNetworks._tr_count_greater, CompositionalNetworks._tr_count_eq_left]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_count_positive |> (y -> CompositionalNetworks._co_vars_minus_val(y; param=param, dom_size=dom_size, nvars=length(x)))
fill(x, 4) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_count_l_left, CompositionalNetworks._tr_count_lesser, CompositionalNetworks._tr_count_greater, CompositionalNetworks._tr_count_eq_right]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_count_positive |> (y -> CompositionalNetworks._co_abs_diff_val_vars(y; param=param, dom_size=dom_size, nvars=length(x)))
end
2 changes: 1 addition & 1 deletion src/compositions/_icn_eq.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
function _icn_eq(x; param=nothing, dom_size)
fill(x, 1) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_count_greater]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_sum |> (y -> CompositionalNetworks._co_identity(y; param=param, dom_size=dom_size, nvars=length(x)))
fill(x, 1) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_count_lesser]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_sum |> (y -> CompositionalNetworks._co_identity(y; param=param, dom_size=dom_size, nvars=length(x)))
end
2 changes: 1 addition & 1 deletion src/compositions/_icn_ordered.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
function _icn_ordered(x; param=nothing, dom_size)
fill(x, 1) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_count_l_right]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_count_positive |> (y -> CompositionalNetworks._co_identity(y; param=param, dom_size=dom_size, nvars=length(x)))
fill(x, 1) .|> map(f -> (y -> f(y; param=param)), [CompositionalNetworks._tr_contiguous_vals_minus]) |> CompositionalNetworks._ar_sum |> CompositionalNetworks._ag_count_positive |> (y -> CompositionalNetworks._co_identity(y; param=param, dom_size=dom_size, nvars=length(x)))
end
14 changes: 1 addition & 13 deletions src/learn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,16 @@ function learn_from_icn()

config = Dict(
:local_iter => 100,
:global_iter => 1,
:global_iter => 10,
:search => :complete,
:metric => hamming,
:population => 400,
)

path = joinpath(dirname(pathof(Constraints)),"compositions")
@info "path" path

for t in targets
@info "Starting learning for $(t.first)"
@info "param" get(t.second, :param, nothing)
err = explore_learn_compose(
concept(usual_constraints[t.first]);
domains=t.second[:domains],
param=get(t.second, :param, nothing),
local_iter=config[:local_iter],
global_iter=config[:global_iter],
search=config[:search],
metric=config[:metric],
popSize=config[:population],
)
name = "_icn_$(t.first)"
compose_to_file!(
concept(usual_constraints[t.first]),
Expand Down

0 comments on commit 427e2f9

Please sign in to comment.