Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling del_component on a ComponentData deletes the parent component #3435

Open
emma58 opened this issue Nov 25, 2024 · 4 comments · May be fixed by #3440
Open

Calling del_component on a ComponentData deletes the parent component #3435

emma58 opened this issue Nov 25, 2024 · 4 comments · May be fixed by #3440
Labels

Comments

@emma58
Copy link
Contributor

emma58 commented Nov 25, 2024

Summary

Calling del_component on a ComponentData (at least for Constraint and Var) deletes the entire parent component.

Steps to reproduce the issue

This script:

from pyomo.environ import *

m = ConcreteModel()
m.x = Var(range(10))
@m.Constraint(range(10))
def c(m, i):
    return m.x[i] <= i

m.pprint()

print("Delete c[5]?")
m.del_component(m.c[5])

m.pprint()

print("Delete x[3]?")
m.del_component(m.x[3])

m.pprint()

Produces this output:

1 Var Declarations
    x : Size=10, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          0 :  None :  None :  None : False :  True :  Reals
          1 :  None :  None :  None : False :  True :  Reals
          2 :  None :  None :  None : False :  True :  Reals
          3 :  None :  None :  None : False :  True :  Reals
          4 :  None :  None :  None : False :  True :  Reals
          5 :  None :  None :  None : False :  True :  Reals
          6 :  None :  None :  None : False :  True :  Reals
          7 :  None :  None :  None : False :  True :  Reals
          8 :  None :  None :  None : False :  True :  Reals
          9 :  None :  None :  None : False :  True :  Reals

1 Constraint Declarations
    c : Size=10, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, Active=True
        Key : Lower : Body : Upper : Active
          0 :  -Inf : x[0] :   0.0 :   True
          1 :  -Inf : x[1] :   1.0 :   True
          2 :  -Inf : x[2] :   2.0 :   True
          3 :  -Inf : x[3] :   3.0 :   True
          4 :  -Inf : x[4] :   4.0 :   True
          5 :  -Inf : x[5] :   5.0 :   True
          6 :  -Inf : x[6] :   6.0 :   True
          7 :  -Inf : x[7] :   7.0 :   True
          8 :  -Inf : x[8] :   8.0 :   True
          9 :  -Inf : x[9] :   9.0 :   True

2 Declarations: x c
Delete c[5]?
1 Var Declarations
    x : Size=10, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          0 :  None :  None :  None : False :  True :  Reals
          1 :  None :  None :  None : False :  True :  Reals
          2 :  None :  None :  None : False :  True :  Reals
          3 :  None :  None :  None : False :  True :  Reals
          4 :  None :  None :  None : False :  True :  Reals
          5 :  None :  None :  None : False :  True :  Reals
          6 :  None :  None :  None : False :  True :  Reals
          7 :  None :  None :  None : False :  True :  Reals
          8 :  None :  None :  None : False :  True :  Reals
          9 :  None :  None :  None : False :  True :  Reals

1 Declarations: x
Delete x[3]?
0 Declarations: 

Error Message

No error--we're turfing the entire IndexedComponent silently.

Information on your system

Pyomo version: main
Python version: 3.11
Operating system: linux
How Pyomo was installed (PyPI, conda, source): source
Solver (if applicable): NA

@emma58 emma58 added the bug label Nov 25, 2024
@jsiirola
Copy link
Member

What would you expect the behavior to be? I could see (at least) two reasonable options:

  • Delete the VarData x[3] from the Component x?
    • But what would you expect to happen if x[3] was the last VarData in x? Also delete the x component?
  • Raise an exception because you passed a ComponentData to something called del_component?
  • Delete the component associated with x[3] (this is what we are doing now)?

...If we make a change, I think I would prefer the second option.

BTW: you can avoid this by always using del and not del_component; that is:

  • del m.x[3] removed the x[3] VarData
  • del m.x removes the entire component

@emma58
Copy link
Contributor Author

emma58 commented Nov 26, 2024

I would vote for either 1 (where when x[3] is the last VarData, x stays on the Block but is empty) or 2. I think 3 is mean because the distinction between Component and ComponentData is subtle in this case. We should also probably document somewhere that del works fine for ComponentDatas and that's why there is no del_component_data.

@emma58
Copy link
Contributor Author

emma58 commented Nov 26, 2024

(The other surprising thing about this is that I'm very surprised we don't hit this mistake in the FME tests...)

@mrmundt
Copy link
Contributor

mrmundt commented Nov 26, 2024

Per the dev call:

  • Raise an exception!
  • Document the difference between del and del_component / their appropriate use cases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants