File mttroot/ntt/bin/trans/m/mttParseOperatorEquations.m artifact aba93f30d1 part of check-in 1a8abdb3d9


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
    

MTT: Model Transformation Tools
GitHub | SourceHut | Sourceforge | Fossil RSS ]