function operator = mttParseOperatorEquations(operator,cr,cr_name) global mtt_environment operator.equation = [] ; % operator.is_used = 0 ; numparlist = cr.numpar ; symparlist = cr.sympar ; varlist = operator.var ; inputlist = cr.input ; statelist = cr.state ; structlist = [] ; if ~isempty(operator.struct) struct_names = mttGetFieldNames(operator,'struct') ; number_of_structs = length(struct_names) ; for i = 1:number_of_structs struct_name = struct_names{i} ; variables = getfield(operator,'struct',struct_name) ; if i==1 structlist = variables ; else structlist = [structlist,variables] ; end end end inlist = [] ; outlist = [] ; inlink = [] ; outlink = [] ; input_counter = 0 ; output_counter = 0 ; for i = 1:length(operator.link) if operator.link(i).is_input input_counter = input_counter + 1 ; inlist{input_counter} = operator.link(i).name ; inlink(input_counter) = i ; infree(input_counter) = operator.link(i).is_unconstrained ; else output_counter = output_counter + 1 ; outlist{output_counter} = operator.link(i).name ; outlink(output_counter) = i ; outfree(output_counter) = operator.link(i).is_unconstrained ; end end operator.assign = [] ; ports_with_state_assignment = [] ; for i = 1:length(operator.set) [port_covariable,state] = mttCutText(operator.set{i},'=>') ; mttAssert(~isempty(state),... ['"set" declarations must use "=>" in cr ',cr_name]) ; [port_name,covariable] = mttCutText(port_covariable,'.') ; mttAssert(~isempty(covariable),... ['"set" declarations must reference effort/flow covariables in cr ',cr_name]) ; port = strmatch(port_name,outlist,'exact') ; ports_with_state_assignment = [ports_with_state_assignment,port] ; mttAssert(~isempty(port),... ['Output port "',port_name,'" not recognised for "set" declaration in cr ',cr_name]) ; mttAssert(outfree(port),... ['Constrained port variable used for "set" declaration in cr ',cr_name]) ; actual_port = getfield(cr.interface.port,port_name) ; mttAssert(actual_port.is_effort_state | actual_port.is_flow_state,... ['"set" declarations must only be used for effort_states or flow_states in cr ',cr_name]) ; if isempty(actual_port.domain) if actual_port.is_effort_state covariables = {'effort'} ; elseif actual_port.is_flow_state covariables = {'flow'} ; end else public_domain = mtt_environment.public_domain(actual_port.domain) ; domain_item = getfield(public_domain.item,actual_port.domain_item) ; if actual_port.is_effort_state covariables = domain_item.effort ; elseif actual_port.is_flow_state covariables = domain_item.flow ; end end index = strmatch(covariable,covariables,'exact') ; mttAssert(~isempty(index),... ['Unrecognised covariable "',covariable,'" used for "set" declaration in cr ',cr_name]) ; if isfield(operator.assign,port_name) assignment = getfield(operator,'assign',port_name) ; mttAssert(isempty(assignment.states{index}),... ['Repeated covariable "',covariable,'" used for "set" declaration in cr ',cr_name]) ; else assignment.covar = covariables ; assignment.state{length(covariables)} = [] ; % assignment.domain = actual_port.domain ; % assignment.domain_item = actual_port.domain_item ; end mttAssert(ismember(state,cr.state),... ['Unrecognised state "',state,'" used for "set" declaration in cr ',cr_name]) ; assignment.state{index} = state ; operator = setfield(operator,'assign',port_name,assignment) ; end operator = mttDeleteField(operator,'set') ; port_assignments = mttGetFieldNames(operator,'assign') ; number_of_assignments = length(port_assignments) ; for i = 1:number_of_assignments assignment = getfield(operator,'assign',port_name) ; for j = 1:length(assignment.state) mttAssert(~isempty(assignment.state{j}),... ['Missing covariable "',covariable,'" from "set" declaration in cr ',cr_name]) ; end end for i = 1:length(operator.content) operator.equation(i).chunk = {[]} ; % operator.equation(i).was_generic = 1 ; % operator.equation(i).domain = [] ; % operator.equation(i).domain_item = [] ; % operator.equation(i).is_effort = [] ; % operator.equation(i).covariable = [] ; counter = 0 ; line = operator.content{i} ; if ~isempty(mttClipText(line)) [var,loc] = mttFindEquationVariables(line) ; if loc(1)>1 front = line(1:loc(1)-1) ; counter = counter + 1 ; operator.equation(i).chunk{counter} = front ; end last = length(line) ; for j = 1:length(var) [name,component] = mttCutText(var{j},'.') ; if isempty(component) [name,attribute] = mttCutText(name,'''') ; numpar = strmatch(name,numparlist,'exact') ; sympar = strmatch(name,symparlist,'exact') ; variable = strmatch(name,varlist,'exact') ; struct = strmatch(name,structlist,'exact') ; input = strmatch(name,inputlist,'exact') ; state = strmatch(name,statelist,'exact') ; ok = ~(isempty(numpar)&isempty(sympar)&isempty(variable)&isempty(struct)&isempty(input)&isempty(state)) ; mttAssert(ok,['Variable ',var{j},' not recognised in cr ',cr_name]) ; is_numpar = ~isempty(numpar) ; is_sympar = ~isempty(sympar) ; is_var = ~isempty(variable) ; is_struct = ~isempty(struct) ; is_input = ~isempty(input) ; is_state = ~isempty(state) ; is_derivative = 0 ; if ~isempty(attribute) mttAssert(strcmp(attribute,'dt'),... ['Unrecognised attribute ',attribute,' in cr ',cr_name]) ; mttAssert(is_state,... ['Derivative of non-state variable in cr ',cr_name]) ; is_state = 0 ; is_derivative = 1 ; end counter = counter + 1 ; if is_numpar operator.equation(i).chunk{counter} = {'numpar',numpar} ; end if is_sympar operator.equation(i).chunk{counter} = {'sympar',sympar} ; end if is_var operator.equation(i).chunk{counter} = {'var',variable} ; end if is_struct operator.equation(i).chunk{counter} = {'struct',struct} ; end if is_input operator.equation(i).chunk{counter} = {'input',input} ; end if is_state operator.equation(i).chunk{counter} = {'state',state} ; end if is_derivative operator.equation(i).chunk{counter} = {'derivative',state} ; end else if j==1 port = strmatch(name,outlist,'exact') ; if ~isempty(ports_with_state_assignment) mttAssert(~any(port==ports_with_state_assignment),... ['Use "set" declaration to assign output port ',name,' to state in cr ',cr_name]) ; end mttAssert(~isempty(port),... ['Output port ',name,' not recognised in cr ',cr_name]) ; mttAssert(outfree(port),... ['Constrained port variable used in cr ',cr_name]) ; counter = counter + 1 ; operator.equation(i).chunk{counter} = {'link',outlink(port),component} ; else port = strmatch(name,inlist,'exact') ; mttAssert(~isempty(port),... ['Input port ',name,' not recognised in cr ',cr_name]) ; mttAssert(infree(port),... ['Constrained port variable used in cr ',cr_name]) ; counter = counter + 1 ; operator.equation(i).chunk{counter} = {'link',inlink(port),component} ; end % equation_domain = mttIdentifyUserDomain(mtt_environment,... % operator.equation(i).domain,.... % operator.equation(i).domain_item) ; covariable = component ; port_name = name ; port = getfield(cr.interface.port,port_name) ; if isempty(port.domain) is_effort = strcmp(covariable,'effort') ; is_flow = strcmp(covariable,'flow') ; mttAssert(is_effort|is_flow, ... ['"',covariable,'" is not a generic covariable']) ; % mttAssert(isempty(operator.equation(i).domain),... % ['Generic interface "',port_name,'" referenced in ',equation_domain,' equation']) ; else public_domain = mtt_environment.public_domain(port.domain) ; actual_domain = getfield(public_domain,'item',port.domain_item) ; port_domain = mttIdentifyUserDomain(mtt_environment,port.domain,port.domain_item) ; is_effort = ismember(covariable,actual_domain.effort) ; is_flow = ismember(covariable,actual_domain.flow) ; mttAssert(is_effort|is_flow, ... ['"',covariable,'" is not a covariable defined in domain "',port_domain,'"']) ; % if isempty(equation_domain) % operator.equation(i).was_generic = 0 ; % operator.equation(i).domain = port.domain ; % operator.equation(i).domain_item = port.domain_item ; % operator.equation(i).covariable = covariable ; % else % mttAssert(covariable==operator.equation(i).covariable, ... % ['Equation cannot combine different covariables: [',covariable,',',operator.equation(i).covariable,']') ; % end end % if isempty(operator.equation(i).is_effort) % if is_effort % operator.equation(i).is_effort = 1 ; % else % operator.equation(i).is_effort = 0 ; % end % else % mttAssert(operator.equation(i).is_effort==is_effort,... % ['Effort and flow covariables appear in equation: "',operator.content{i},'"']) ; % end end next = loc(j) + length(var{j}) ; if j<length(var) glue = line(next:loc(j+1)-1) ; counter = counter + 1 ; operator.equation(i).chunk{counter} = glue ; if j==1 mttAssert(~isempty(findstr(glue,':=')),... ['Expect ":=" after first variable in cr ',cr_name]) ; end else if next<=last back = line(next:last) ; counter = counter + 1 ; operator.equation(i).chunk{counter} = back ; end end end end end