MathematicalSystems.jl icon indicating copy to clipboard operation
MathematicalSystems.jl copied to clipboard

Error handling for repeated variable names (cont.)

Open mforets opened this issue 5 years ago • 3 comments

In https://github.com/JuliaReach/MathematicalSystems.jl/pull/164 we added default variable names in parse_system and an error message is sent in case of conflict. However, the noise variable is read a posteriori so there is still a possible conflict. As a consequence the following error is a bit cryptic and can be improved:

julia> @system(x⁺ = Ax + Bu + Du, input: u)
ERROR: ArgumentError: the entry (:A, :B, :B) does not match a `MathematicalSystems.jl` structure

ref: https://github.com/JuliaReach/MathematicalSystems.jl/pull/164#discussion_r378106601

An approach suggested here is to make the error checks in extract_sum.

mforets avatar Feb 21 '20 14:02 mforets

After thinking everything through more again more carefully, I think you are right.

In order for me to understand what is going on, I like to write everything I know down (sorry for the long comment)

As far as i know, this PR should give reasonable error messages for cases where a specified input or noise is added which does collide with another

A = B = D = rand(2,2)
@system(a⁺= Aa + Bw, input:a)
ERROR: ArgumentError: state and input variables have the same name `a`
# instead of the old error message
ERROR: ArgumentError: the entry (:A, :D) does not match a `MathematicalSystems.jl` structure
@system(x⁺= Ax + Bx, input:x)
ERROR: ArgumentError: state and input variables have the same name `x`
@system(x⁺= Ax + Bu + Bw, input:u, noise:u)
ERROR: ArgumentError: input and noise variables have the same name `u`

without throwing exceptions where the input is "overwritten" with the noise variable (and the noise not defined) or vice versa where the input is overwritten

# we can use 
@system(x⁺= Ax + Bw, input:w) #creates a LinearControlDiscreteSystem system
system(x⁺= Ax + Bu, noise:u) # 
# instead of 
@system(x⁺= Ax + Bw, input:w, noisestr:evry_but_w)

in the @system(x⁺= Ax + Bw, input:w), the input and the noise variable are both :w but since we do not "use" the noise variable we accept that "inconsistency" for shortness of the macro.

However, this cases are not covered so far in this PR (but we also should add it)

@system(x⁺= Ax + Bw + Dw, input:w)
@system(x⁺= Ax + Bu + Bu,  noise:u)
@system(x⁺= Ax + Bx)
@system(x⁺= Ax + c + c)
# etc

which gives a non-sensical error messsage. (for which my aforementioned fix should help).

Hoooowever, going through this logic it should also give the right error for

@system(x⁺= Ax + Bu + Bw,  noise:u)
ERROR: ArgumentError: the entry (:A, :B, :c) does not match a `MathematicalSystems.jl` structure
@system(x⁺= Ax + Bu + Bw,  input:w)
ERROR: ArgumentError: the entry (:A, :c, :B) does not match a `MathematicalSystems.jl` structure

which it does not, and also will not get caught by my solutions.

Sooo, too sum up, I am bit confused. I think we could do it better, you are right, but I am not sure how. Maybe throwing the error at a later stage, where we no the exact system types and all the variables.

EDIT: noo, it does not work to make the test later, because we will infer the wrong system types

originally posted in https://github.com/JuliaReach/MathematicalSystems.jl/pull/164#issuecomment-589700785

we still have to catch the error from @system(x⁺= Ax + Bu + Bw, noise:u) and @system(x⁺= Ax + Bu + Bw, input:w) I think this one could be caught after here after this line https://github.com/JuliaReach/MathematicalSystems.jl/blob/a1d94d6658d6e7e6983e9fd5ef7783c20fb72b5f/src/macros.jl#L807... it is getting quite ugly if we have 3 separate places for tests.

mforets avatar Feb 21 '20 15:02 mforets

I found a new error, that the tests in parse_system introduce:

@system(x' = A*x + B*w, noise:w)
ERROR: ArgumentError: input and noise variables have the same name `w`

throws an error because we set the input here

 if @capture(stripped, (x_ = A_*x_ + B_*u_) |
                          (x_ = x_ + B_*u_) |
                          (x_ = A_*x_ + B_*u_ + c_) |
                          (x_ = x_ + B_*u_ + c_) |
                          (x_ = f_(x_, u_)) )
      input_var = u
 end

and then here

elseif got_input_var && got_noise_var && (input_var == noise_var)
         throw(ArgumentError("input and noise variables have the same name `$(input_var)`"))
end

it "breaks".

All the convenience functions and special cases are taking its toll.

ueliwechsler avatar Feb 22 '20 23:02 ueliwechsler

https://github.com/JuliaReach/MathematicalSystems.jl/pull/186#discussion_r382987254

Summary:

Not properly working are:

  • [ ] @system(x' = A*x + B*w, noise:w) ERROR: ArgumentError: input and noise variables have the same name w
  • [ ] @system(x⁺= Ax + Bu + Bw, noise:u) ArgumentError: the entry (:A, :B, :c) does not match a MathematicalSystems.jl structure
  • [ ] @system(x⁺= Ax + Bu + Bw, input:w)

ueliwechsler avatar Mar 09 '20 12:03 ueliwechsler