-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathcontractor.jl
75 lines (56 loc) · 1.99 KB
/
contractor.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
immutable Contractor{F1<:Function, F2<:Function}
variables::Vector{Symbol} # input variables
num_outputs::Int
forward::F1
backward::F2
forward_code::Expr
backward_code::Expr
end
# function Base.show(io::IO, C::Contractor)
# println(io, "Contractor:")
# println(io, " - variables: $(C.variables)")
# print(io, " - constraint: $(C.constraint_expression)")
# end
doc"""Usage:
```
C = @contractor(x^2 + y^2)
A = -∞..1 # the constraint interval
x = y = @interval(0.5, 1.5)
C(A, x, y)
`@contractor` makes a function that takes as arguments the variables contained in the expression, in lexicographic order
```
TODO: Hygiene for global variables, or pass in parameters
"""
macro contractor(ex)
make_contractor(ex)
end
@compat function (C::Contractor{F1,F2}){F1,F2}(A, X) # X::IntervalBox)
z = IntervalBox( C.forward(IntervalBox(X...)...)... )
#z = [1:C.num_outputs] = tuple(IntervalBox(z[1:C.num_outputs]...) ∩ A
# @show z
constrained = IntervalBox(z[1:C.num_outputs]...) ∩ IntervalBox(A...)
#@show constrained
#@show z[(C.num_outputs)+1:end]
return IntervalBox( C.backward( X...,
constrained...,
z[(C.num_outputs)+1:end]...
)...
)
end
function make_contractor(ex::Expr)
# println("Entering Contractor(ex) with ex=$ex")
expr, constraint_interval = parse_comparison(ex)
if constraint_interval != entireinterval()
warn("Ignoring constraint; include as first argument")
end
top, linear_AST = flatten(expr)
# @show top, linear_AST
forward, backward = forward_backward(linear_AST)
num_outputs = isa(linear_AST.top, Symbol) ? 1 : length(linear_AST.top)
:(Contractor($linear_AST.variables,
$num_outputs,
$forward,
$backward,
$(Meta.quot(forward)),
$(Meta.quot(backward))))
end