5858# ##
5959# ## Structural check
6060# ##
61- function  check_consistency (state:: TransformationState , orig_inputs)
61+ 
62+ """ 
63+     $(TYPEDSIGNATURES)  
64+ 
65+ Check if the `state` represents a singular system, and return the unmatched variables. 
66+ """ 
67+ function  singular_check (state:: TransformationState )
68+     @unpack  graph, var_to_diff =  state. structure
69+     fullvars =  get_fullvars (state)
70+     #  This is defined to check if Pantelides algorithm terminates. For more
71+     #  details, check the equation (15) of the original paper.
72+     extended_graph =  (@set  graph. fadjlist =  Vector{Int}[graph. fadjlist;
73+                                                         map (collect, edges (var_to_diff))])
74+     extended_var_eq_matching =  maximal_matching (extended_graph)
75+ 
76+     nvars =  ndsts (graph)
77+     unassigned_var =  []
78+     for  (vj, eq) in  enumerate (extended_var_eq_matching)
79+         vj >  nvars &&  break 
80+         if  eq ===  unassigned &&  ! isempty (𝑑neighbors (graph, vj))
81+             push! (unassigned_var, fullvars[vj])
82+         end 
83+     end 
84+     return  unassigned_var
85+ end 
86+ 
87+ """ 
88+     $(TYPEDSIGNATURES)  
89+ 
90+ Check the consistency of `state`, given the inputs `orig_inputs`. If `nothrow == false`, 
91+ throws an error if the system is under-/over-determined or singular. In this case, if the 
92+ function returns it will return `true`. If `nothrow == true`, it will return `false` 
93+ instead of throwing an error. The singular case will print a warning. 
94+ """ 
95+ function  check_consistency (state:: TransformationState , orig_inputs; nothrow =  false )
6296    fullvars =  get_fullvars (state)
6397    neqs =  n_concrete_eqs (state)
6498    @unpack  graph, var_to_diff =  state. structure
@@ -72,6 +106,7 @@ function check_consistency(state::TransformationState, orig_inputs)
72106    is_balanced =  n_highest_vars ==  neqs
73107
74108    if  neqs >  0  &&  ! is_balanced
109+         nothrow &&  return  false 
75110        varwhitelist =  var_to_diff .==  nothing 
76111        var_eq_matching =  maximal_matching (graph, eq ->  true , v ->  varwhitelist[v]) #  not assigned
77112        #  Just use `error_reporting` to do conditional
@@ -85,22 +120,12 @@ function check_consistency(state::TransformationState, orig_inputs)
85120        error_reporting (state, bad_idxs, n_highest_vars, iseqs, orig_inputs)
86121    end 
87122
88-     #  This is defined to check if Pantelides algorithm terminates. For more
89-     #  details, check the equation (15) of the original paper.
90-     extended_graph =  (@set  graph. fadjlist =  Vector{Int}[graph. fadjlist;
91-                                                         map (collect, edges (var_to_diff))])
92-     extended_var_eq_matching =  maximal_matching (extended_graph)
93- 
94-     nvars =  ndsts (graph)
95-     unassigned_var =  []
96-     for  (vj, eq) in  enumerate (extended_var_eq_matching)
97-         vj >  nvars &&  break 
98-         if  eq ===  unassigned &&  ! isempty (𝑑neighbors (graph, vj))
99-             push! (unassigned_var, fullvars[vj])
100-         end 
101-     end 
123+     unassigned_var =  singular_check (state)
102124
103125    if  ! isempty (unassigned_var) ||  ! is_balanced
126+         if  nothrow
127+             return  false 
128+         end 
104129        io =  IOBuffer ()
105130        Base. print_array (io, unassigned_var)
106131        unassigned_var_str =  String (take! (io))
@@ -110,7 +135,7 @@ function check_consistency(state::TransformationState, orig_inputs)
110135        throw (InvalidSystemException (errmsg))
111136    end 
112137
113-     return  nothing 
138+     return  true 
114139end 
115140
116141# ##
0 commit comments