Skip to content

Commit 775fa9d

Browse files
committed
add CurryAtom and replace SetAtom
1 parent a0716dd commit 775fa9d

File tree

8 files changed

+73
-72
lines changed

8 files changed

+73
-72
lines changed

docs/make.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ makedocs(; sitename="MathematicalPredicates.jl",
1010
assets=["assets/aligned.css"]),
1111
pagesonly=true,
1212
pages=["Home" => "index.md",
13-
"Library" => ["Predicates" => "lib/predicates.md",
14-
"LazySets integration" => "lib/LazySets.md"],
13+
"Library" => ["Predicates" => "lib/predicates.md"],
1514
"About" => "about.md"])
1615

1716
deploydocs(; repo="github.com/JuliaReach/MathematicalPredicates.jl.git",

docs/src/lib/LazySets.md

Lines changed: 0 additions & 17 deletions
This file was deleted.

docs/src/lib/predicates.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,9 @@ Conjunction
3939
```@docs
4040
Disjunction
4141
```
42+
43+
## CurryAtom
44+
45+
```@docs
46+
CurryAtom
47+
```

src/CurryAtom.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
"""
3+
CurryAtom{N,A,T} <: Predicate{N}
4+
5+
An atomic predicate of arity `N` defined via a fixed first argument and an
6+
`N+1`-ary predicate.
7+
8+
### Fields
9+
10+
- `arg1` -- first argument
11+
- `p` -- `N+1`-ary predicate that takes `arg1` as first argument
12+
"""
13+
struct CurryAtom{N,A,T<:Predicate} <: Predicate{N}
14+
arg1::A
15+
p::T
16+
17+
function CurryAtom(arg1::A, p::T; N::Int=1) where {A,T<:Predicate}
18+
return new{Val{N},A,T}(arg1, p)
19+
end
20+
end
21+
22+
# function-like evaluation
23+
@inline function (ca::CurryAtom)(args...)
24+
return evaluate(ca, args...)
25+
end
26+
27+
function evaluate(ca::CurryAtom, args...)
28+
assert_same_length(ca, args...)
29+
return evaluate(ca.p, ca.arg1, args...)
30+
end
31+
32+
function Base.:(==)(ca1::CurryAtom, ca2::CurryAtom)
33+
return ca1.arg1 == ca2.arg1 && ca1.p == ca2.p
34+
end

src/MathematicalPredicates.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
module MathematicalPredicates
22

3-
export Predicate, Atom, Negation, Conjunction, Disjunction,
3+
export Predicate, Atom, Negation, Conjunction, Disjunction, CurryAtom,
44
evaluate
55

66
include("Predicate.jl")
77
include("Atom.jl")
88
include("Negation.jl")
99
include("Conjunction.jl")
1010
include("Disjunction.jl")
11+
include("CurryAtom.jl")
1112

1213
# optional dependencies
1314
using Requires

src/init_LazySets.jl

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export SetAtom, contains, is_contained_in, is_disjoint_from, intersects
1+
export contains, is_contained_in, is_disjoint_from, intersects
22
import .LazySets: dim, project
33

44
@static if VERSION >= v"1.5"
@@ -7,66 +7,35 @@ end
77

88
using .LazySets: LazySet, , isdisjoint
99

10-
"""
11-
SetAtom{S<:LazySet, T} <: Predicate{Val{1}}
12-
13-
A unary atomic predicate defined with respect to a set.
14-
15-
### Fields
16-
17-
- `X` -- set
18-
- `f` -- function that takes the set `X` as first argument
19-
"""
20-
struct SetAtom{S<:LazySet,T} <: Predicate{Val{1}}
21-
X::S
22-
f::T
23-
24-
function SetAtom(X::S, f::T) where {S<:LazySet,T}
25-
return new{S,T}(X, f)
26-
end
27-
end
28-
29-
# function-like evaluation
30-
@inline function (sa::SetAtom)(args...)
31-
return evaluate(sa, args...)
32-
end
33-
34-
function evaluate(sa::SetAtom, args...)
35-
assert_same_length(sa, args...)
36-
return sa.f(sa.X, args...)
37-
end
38-
39-
function Base.:(==)(sa1::SetAtom, sa2::SetAtom)
40-
return sa1.X == sa2.X && sa1.f == sa2.f
41-
end
10+
const SetAtom = CurryAtom{<:Any,<:LazySet}
4211

4312
# ===========================
4413
# Dimension of set predicates
4514
# ===========================
4615

4716
function dim(sa::SetAtom)
48-
return dim(sa.X)
17+
return dim(sa.arg1)
4918
end
5019

5120
# fallback
5221
function dim(p::Predicate)
5322
throw(ArgumentError("`dim` cannot be applied to a `$(typeof(p))`; use a " *
54-
"`SetAtom` instead"))
23+
"`CurryAtom` with a set instead"))
5524
end
5625

5726
# ============================
5827
# Projection of set predicates
5928
# ============================
6029

6130
function project(sa::SetAtom, vars::AbstractVector{Int})
62-
X_proj = project(sa.X, vars)
63-
return SetAtom(X_proj, sa.f)
31+
X_proj = project(sa.arg1, vars)
32+
return CurryAtom(X_proj, sa.p)
6433
end
6534

6635
# fallback
67-
function project(p::Predicate, vars::AbstractVector{Int})
36+
function project(p::Predicate, ::AbstractVector{Int})
6837
throw(ArgumentError("`project` cannot be applied to a `$(typeof(p))`; " *
69-
"use a `SetAtom` instead"))
38+
"use a `CurryAtom` with a set instead"))
7039
end
7140

7241
function project(n::Negation, vars::AbstractVector{Int})
@@ -94,15 +63,15 @@ end
9463
# ==========================================
9564

9665
function contains(X::LazySet)
97-
return SetAtom(X, )
66+
return CurryAtom(X, Atom(; N=2))
9867
end
9968

10069
function is_contained_in(X::LazySet)
101-
return SetAtom(X, (X, Y) -> Y X)
70+
return CurryAtom(X, Atom((X, Y) -> Y X; N=2))
10271
end
10372

10473
function is_disjoint_from(X::LazySet)
105-
return SetAtom(X, isdisjoint)
74+
return CurryAtom(X, Atom(isdisjoint; N=2))
10675
end
10776

10877
function intersects(X::LazySet)

test/LazySets.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@ P1 = is_contained_in(B1)
1313
P2 = contains(S)
1414
@test P2(S) && P2(B1) && !P2(B2)
1515

16-
# dim is only available for SetAtom types
16+
# dim is only available for CurryAtom types
1717
A1 = Atom(x -> x > 1)
1818
@test_throws ArgumentError dim(A1)
1919

20-
# project is only available for SetAtom (and their Negation) types
20+
# project is only available for CurryAtom (and their Negation) types
2121
@test_throws ArgumentError project(A1, [1])
2222

2323
@test project(Negation(P1), [1]) == Negation(project(P1, [1]))
2424

2525
@test dim(P1) == dim(P2) == 2
2626
P1_proj = project(P1, [1])
2727
P2_proj = project(P2, [1])
28-
@test P1_proj isa SetAtom && dim(P1_proj) == 1 && P1_proj.X == B1_proj
28+
@test P1_proj isa CurryAtom && dim(P1_proj) == 1 && P1_proj.arg1 == B1_proj
2929
@test P1_proj(S_proj) && P1_proj(B1_proj) && !P1_proj(B2_proj)
30-
@test P2_proj isa SetAtom && dim(P2_proj) == 1 && P2_proj.X == S_proj
30+
@test P2_proj isa CurryAtom && dim(P2_proj) == 1 && P2_proj.arg1 == S_proj
3131
@test P2_proj(S_proj) && P2_proj(B1_proj) && !P2_proj(B2_proj)
3232

3333
Pc = Conjunction([P1, P2])

test/basic.jl

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# atom
1+
# Atom
22
a0 = Atom(() -> true; N=0)
33
a1 = Atom(x -> x > 1)
44
a2 = Atom((x, y) -> x > y; N=2)
@@ -9,7 +9,7 @@ a2 = Atom((x, y) -> x > y; N=2)
99
@test !evaluate(a2, 4, 5) && !a2(4, 5)
1010
@test evaluate(a2, 6, 5) && a2(6, 5)
1111

12-
# negation
12+
# Negation
1313
n0 = Negation(a0)
1414
n1 = Negation(a1)
1515
n2 = Negation(a2)
@@ -20,7 +20,7 @@ n2 = Negation(a2)
2020
@test evaluate(n2, 4, 5) && n2(4, 5)
2121
@test !evaluate(n2, 6, 5) && !n2(6, 5)
2222

23-
# conjunction
23+
# Conjunction
2424
c0 = Conjunction([(n0, Int[]), (a0, Int[])]; N=0)
2525
c0_3 = Conjunction([(a0, Int[]), (a0, Int[]), (a0, Int[])]; N=0)
2626
c1 = Conjunction([(a0, Int[]), (a1, Int[1])]; N=1)
@@ -40,7 +40,7 @@ c2_3 = Conjunction([(a0, Int[]), (a1, Int[2]), (a2, Int[2, 1])]; N=2)
4040
@test Conjunction([(a0, Int[]), (a0, Int[]), (a0, Int[])]) isa Conjunction{Val{0}}
4141
@test Conjunction([(a0, Int[]), (a1, Int[2]), (a2, Int[2, 1])]) isa Conjunction{Val{2}}
4242

43-
# disjunction
43+
# Disjunction
4444
d0 = Disjunction([(n0, Int[]), (a0, Int[])]; N=0)
4545
d0_3 = Disjunction([(n0, Int[]), (n0, Int[]), (n0, Int[])]; N=0)
4646
d1 = Disjunction([(c0, Int[]), (a1, Int[1])]; N=1)
@@ -56,18 +56,27 @@ d2_3 = Disjunction([(a0, Int[]), (a1, Int[2]), (a2, Int[2, 1])]; N=2)
5656
@test evaluate(d2, 4, 5) && d2(4, 5)
5757
@test evaluate(d2_3, 4, 5) && d2_3(4, 5)
5858

59+
# CurryAtom
60+
ca0a = CurryAtom(2, a1; N=0)
61+
@test evaluate(ca0a)
62+
ca0b = CurryAtom(0, a1; N=0)
63+
@test !evaluate(ca0b)
64+
@test ca0a == ca0a && ca0a != ca0b
65+
ca1 = CurryAtom(3, a2; N=1)
66+
@test evaluate(ca1, 2) && !evaluate(ca1, 4)
67+
5968
# default constructor
6069
@test Disjunction([(a0, Int[]), (a0, Int[]), (a0, Int[])]) isa Disjunction{Val{0}}
6170
@test Disjunction([(a0, Int[]), (a1, Int[2]), (a2, Int[2, 1])]) isa Disjunction{Val{2}}
6271

63-
# unary conjunction
72+
# unary Conjunction
6473
cu = Conjunction([n1, a1])
6574
cu_3 = Conjunction([c1, a1, d1])
6675

6776
@test !evaluate(cu, 5) && !cu(5)
6877
@test evaluate(cu_3, 5) && cu_3(5)
6978

70-
# unary disjunction
79+
# unary Disjunction
7180
du = Disjunction([n1, a1])
7281
du_1 = Disjunction([n1])
7382

0 commit comments

Comments
 (0)