123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- function model = mttApplyInterfaceCausality(model,specified_rule,branch) ;
- is_root_model = (nargin==2) ;
-
- objects = mttGetFieldNames(model,'obj') ;
-
- for i = 1:length(objects)
- object_name = objects{i} ;
- object = getfield(model,'obj',object_name) ;
-
- if isfield(object,'obj')
- if is_root_model
- branch = object_name ;
- else
- branch = [branch,'/',object_name] ;
- end
-
- object = mttApplyInterfaceCausality(object,specified_rule,branch) ;
- model = setfield(model,'obj',object_name,object) ;
-
- else
- if ~isempty(object.cr)
- if is_root_model
- branch = mttDetachText(model.source,'/') ;
- end
- here = [branch,':',object_name] ;
-
- port_names = mttGetFieldNames(object.cr.interface,'port') ;
-
- for j = 1:length(port_names)
- port_name = port_names{j} ;
- port = getfield(object.cr.interface,'port',port_name) ;
-
- inbond = port.in ;
- outbond = port.out ;
-
- for k = 1:mttGetFieldLength(port,'causality')
- rule = port.causality(k).rule ;
- definition = port.causality(k).def ;
- association = port.causality(k).with ;
- not_applied = ~port.causality(k).applied ;
-
- switch rule
- case 'assert', is_assertion = 1 ;
- case 'prefer', is_assertion = 0 ;
- otherwise
- error(['Unrecognised rule "',port_causality.rule,'" in ',here]) ;
- end
-
- apply_rule = strcmp(specified_rule,rule) & not_applied ;
- if apply_rule
-
- switch definition
- % case 'effort_state',
- % mttAssert(mttIsEqual(port.is_flow_state,0),...
- % ['Attempt to overwrite state assignment at port "',port_name,'" in ',here]) ;
- % port.is_effort_state = 1 ;
-
- % case 'flow_state',
- % mttAssert(mttIsEqual(port.is_effort_state,0),...
- % ['Attempt to overwrite state assignment at port "',port_name,'" in ',here]) ;
- % port.is_flow_state = 1 ;
-
- case {'effort_in_flow_out','flow_in_effort_out','flow_out_effort_in','effort_out_flow_in'}
- mttAssert(isempty(association),...
- ['Over-constraint at port "',port_name,'" in ',here]) ;
-
- switch definition
- case {'effort_in_flow_out','flow_out_effort_in'},
- [model,inbond_ok] = mttUpdateBondCausality(model,inbond,1,1,1) ;
- [model,outbond_ok] = mttUpdateBondCausality(model,outbond,0,0,1) ;
- case {'flow_in_effort_out','effort_out_flow_in'},
- [model,inbond_ok] = mttUpdateBondCausality(model,inbond,0,0,1) ;
- [model,outbond_ok] = mttUpdateBondCausality(model,outbond,1,1,1) ;
- end
- ok = inbond_ok & outbond_ok ;
- if is_assertion
- mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ;
- end
-
- case 'effort_in'
- mttAssert(isempty(association),...
- ['Over-constraint at port "',port_name,'" in ',here]) ;
-
- [model,inbond_ok] = mttUpdateBondCausality(model,inbond,1,[],1) ;
- [model,outbond_ok] = mttUpdateBondCausality(model,outbond,0,[],1) ;
- ok = inbond_ok & outbond_ok ;
- if is_assertion
- mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ;
- end
-
- case 'effort_out'
- mttAssert(isempty(association),...
- ['Over-constraint at port "',port_name,'" in ',here]) ;
-
- [model,inbond_ok] = mttUpdateBondCausality(model,inbond,0,[],1) ;
- [model,outbond_ok] = mttUpdateBondCausality(model,outbond,1,[],1) ;
- ok = inbond_ok & outbond_ok ;
- if is_assertion
- mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ;
- end
-
- case 'flow_in'
- mttAssert(isempty(association),...
- ['Over-constraint at port "',port_name,'" in ',here]) ;
-
- [model,inbond_ok] = mttUpdateBondCausality(model,inbond,[],0,1) ;
- [model,outbond_ok] = mttUpdateBondCausality(model,outbond,[],1,1) ;
- ok = inbond_ok & outbond_ok ;
- if is_assertion
- mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ;
- end
-
- case 'flow_out'
- mttAssert(isempty(association),...
- ['Over-constraint at port "',port_name,'" in ',here]) ;
-
- [model,inbond_ok] = mttUpdateBondCausality(model,inbond,[],1,1) ;
- [model,outbond_ok] = mttUpdateBondCausality(model,outbond,[],0,1) ;
- ok = inbond_ok & outbond_ok ;
- if is_assertion
- mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ;
- end
-
- case 'unicausal',
- mttAssert(isempty(association),...
- ['Over-constraint at port "',port_name,'" in ',here]) ;
-
- [model,inbond_ok] = mttUpdateBondCausality(model,inbond,[],[],1) ;
- [model,outbond_ok] = mttUpdateBondCausality(model,outbond,[],[],1) ;
-
- ok = inbond_ok & outbond_ok ;
- if is_assertion
- mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ;
- end
-
- case {'equicausal','anticausal'}
- mttAssert(length(association)==1,...
- ['Incorrect constraint at port "',port_name,'" in ',here]) ;
-
- associated_port_name = association{1} ;
- associated_port = getfield(cr.interface,'port',associated_port_name) ;
-
- associated_inbond = associated_port.in ;
- associated_outbond = associated_port.out ;
-
- mttAsert(xor(isempty(inbond),isempty(outbond)),...
- ['Causal rule expects unique bond at port "',port_name,'" in ',here]) ;
- mttAsert(xor(isempty(associated_inbond),isempty(associated_outbond)),...
- ['Causal rule expects unique bond at port "',associated_port_name,'" in ',here]) ;
-
- if isempty(associated_inbond)
- a = associated_outbond ;
- else
- a = associated_inbond ;
- end
-
- if isempty(inbond)
- b = outbond ;
- else
- b = inbond ;
- end
-
- switch definition
- case 'equicausal',
- [model,bond_ok] = mttUpdateBondCausality(model,b,...
- model.bond(a).effort,model.bond(a).flow,model.bond(a).unicausal) ;
- [model,associated_bond_ok] = mttUpdateBondCausality(model,a,...
- model.bond(b).effort,~model.bond(b).flow,model.bond(b).unicausal) ;
- case 'anticausal',
- [model,bond_ok] = mttUpdateBondCausality(model,b,...
- ~model.bond(a).effort,model.bond(a).flow,model.bond(a).unicausal) ;
- [model,associated_bond_ok] = mttUpdateBondCausality(model,a,...
- ~model.bond(b).effort,~model.bond(b).flow,model.bond(b).unicausal) ;
- end
-
- ok = bond_ok & associated_bond_ok ;
- if is_assertion
- mttAssert(ok,['Causal conflict between ports "',port_name,...
- 'and',associated_port_name,'" in ',here]) ;
- end
-
- otherwise,
- error(['Unrecognised constraint "',definition,'" in ',here]) ;
- end
-
- port.causality(k).applied = 1 ;
- object = setfield(object,'cr','interface','port',port_name,port) ;
- model = setfield(model,'obj',object_name,object) ;
- end
- end
- end
- end
- end
- end
-
|