@@ -133,6 +133,7 @@ const _KEYWORDS = Dict(
133133 _TOKEN_LESS_THAN,
134134 _TOKEN_EQUAL_TO,
135135 _TOKEN_COLON,
136+ _TOKEN_IMPLIES,
136137 _TOKEN_NEWLINE,
137138 _TOKEN_UNKNOWN,
138139)
@@ -270,8 +271,11 @@ function _peek_inner(state::LexerState)
270271 end
271272 return Token (_TOKEN_IDENTIFIER, val)
272273 elseif (op = get (_OPERATORS, c, nothing )) != = nothing
273- read (state, Char)
274- if c in (' <' , ' >' , ' =' ) && peek (state, Char) == ' ='
274+ read (state, Char) # Skip c
275+ if c == ' -' && peek (state, Char) == ' >'
276+ read (state, Char)
277+ return Token (_TOKEN_IMPLIES, " ->" )
278+ elseif c in (' <' , ' >' , ' =' ) && peek (state, Char) == ' ='
275279 read (state, Char) # Allow <=, >=, and ==
276280 end
277281 return Token (op, string (c))
@@ -718,14 +722,52 @@ function _is_sos_constraint(state)
718722 _next_token_is (state, _TOKEN_COLON, 3 )
719723end
720724
725+ function _is_indicator_constraint (state)
726+ return _next_token_is (state, _TOKEN_IDENTIFIER, 1 ) &&
727+ _next_token_is (state, _TOKEN_EQUAL_TO, 2 ) &&
728+ _next_token_is (state, _TOKEN_NUMBER, 3 ) &&
729+ _next_token_is (state, _TOKEN_IMPLIES, 4 )
730+ end
731+
732+ # INDICATOR_CONSTRAINT :=
733+ # IDENTIFIER "=" "0" "->" EXPRESSION SET_SUFFIX
734+ # | IDENTIFIER "=" "1" "->" EXPRESSION SET_SUFFIX
735+ function _parse_indicator_constraint (
736+ state:: LexerState ,
737+ cache:: Cache{T} ,
738+ ) where {T}
739+ z = _parse_variable (state, cache)
740+ _expect (read (state, Token), _TOKEN_EQUAL_TO)
741+ t = read (state, Token)
742+ _expect (t, _TOKEN_NUMBER)
743+ indicator = if t. value == " 0"
744+ MOI. ACTIVATE_ON_ZERO
745+ elseif t. value == " 1"
746+ MOI. ACTIVATE_ON_ONE
747+ else
748+ throw (UnexpectedToken (t))
749+ end
750+ _expect (read (state, Token), _TOKEN_IMPLIES)
751+ f = _parse_expression (state, cache)
752+ set = _parse_set_suffix (state, cache)
753+ return MOI. add_constraint (
754+ cache. model,
755+ MOI. Utilities. operate (vcat, T, z, f),
756+ MOI. Indicator {indicator} (set),
757+ )
758+ end
759+
721760# CONSTRAINT :=
722761# [NAME] EXPRESSION SET_SUFFIX
723762# | [NAME] SOS_CONSTRAINT
763+ # | [NAME] INDICATOR_CONSTRAINT
724764function _parse_constraint (state:: LexerState , cache:: Cache )
725765 name = _parse_optional_name (state, cache)
726766 # Check if this is an SOS constraint
727767 c = if _is_sos_constraint (state)
728768 _parse_sos_constraint (state, cache)
769+ elseif _is_indicator_constraint (state)
770+ _parse_indicator_constraint (state, cache)
729771 else
730772 f = _parse_expression (state, cache)
731773 set = _parse_set_suffix (state, cache)
0 commit comments