-----------------------------------------------------------------------
-- Copyright (C) 2015-2016                                           --
-- University of Firenze, Italy                                      --
--                                                                   --
-- All rights reserved. This program and the accompanying materials  --
-- are made available under the terms of the Eclipse Public License  --
-- v1.0 which accompanies this distribution, and is available at     --
-- http://www.eclipse.org/legal/epl-v20.html                         --
--                                                                   --
-- Contributors:                                                     --
-- Leonardo Montecchi 	lmontecchi@unifi.it                          --
-----------------------------------------------------------------------

-- @path IM=/org.polarsys.chess.statebased/metamodels/IM2.ecore
-- @path CHESS=/org.polarsys.chess.chessmlprofile/model/chessmlprofile.ecore
-- @nsURI MARTE=http://www.eclipse.org/papyrus/MARTE/1
-- @nsURI UML=http://www.eclipse.org/uml2/4.0.0/UML
-- @nsURI CHESS=http://CHESS
-- @nsURI SYSML=http://www.eclipse.org/papyrus/0.7.0/SysML

module CHESS2IM;
create OUT : IM from IN1 : CHESS, IN2 : UML, IN3 : MARTE, IN4 : SYSML;

helper def: umlInstancesAll : Sequence(UML!InstanceSpecification) = Sequence{}; 	--All the InstanceSpecification of the considered platform
helper def: umlInstancesConnectors : Set(UML!InstanceSpecification) = Set{};		--Instances of connectors
helper def: umlInstancesBlocks : Set(UML!InstanceSpecification) = Set{}; 			--Instances of components/blocks
helper def: umlInstancesStereo : Set(UML!InstanceSpecification) = Set{}; 			--Instances that have dependability information
helper def: umlInstancesRelevant : Set(UML!InstanceSpecification) = Set{}; 			--Instances that are relevant for the analysis
helper def: umlAllocations : Set(MARTE!Assign) = Set{};

--Stereotypes that can be used on Blocks/Components for state based analysis
helper def: sbaStereotypes : Sequence(OclAny) = Sequence{CHESS!SimpleStochasticBehavior, CHESS!FLABehavior, CHESS!ErrorModelBehavior,
														 CHESS!StatelessSoftware, CHESS!StatefulSoftware, CHESS!StatelessHardware, CHESS!StatefulHardware};
--Stereotypes that can be used on Transitions of an Error Model
helper def: sbaTransitions : Sequence(OclAny) = Sequence{CHESS!Failure, CHESS!InternalPropagation, CHESS!InternalFault};														 
helper def: flaNoFailure : String = 'noFailure';
helper def: flaWildcard : String = 'wildcard';
													 
helper def: flaRules : Map(IM!Component, Map(String, IM!Error)) = Map{};			--Map to obtain the list of flarules for a component, and the corresponding IM!Error elements

helper def: errmodErrorMap : Map(TupleType(e: UML!Vertex, cc: IM!Component), IM!Error) = Map{};

--rule to transform the CHESS!StateBasedAnalysis into an IM!Sistema
rule SBA {
	from 
		sba : CHESS!StateBasedAnalysis
	do {
		thisModule.System(sba.platform->first().base_Package);
		
		--Handle metrics
		if (sba.WhichMeasure = 'Reliability') {
			thisModule.Reliability(sba);
		}else if (sba.WhichMeasure = 'Availability') {
			thisModule.Availability(sba);
		}else if (sba.WhichMeasure = 'PFD') {
			thisModule.PFD(sba);
		}else{
			---TODO: others?
		}
	}
}

unique lazy rule System {
	from
		platform : UML!Package	
	--sba : CHESS!StateBasedAnalysis
		--at the moment is it implied that there is only a StateBasedAnalysis in the model
	using {
		--instances of interest are:
		--> SET1: all the instances included in the target resource platform, plus
		--> SET2: all the instances involved in allocations mentioned in the target resource platform, plus
		--> SET3: all the instances in the same resource platform as those involved in allocations
		instances : Set(UML!InstanceSpecification) = 
			UML!InstanceSpecification.allInstances()->select(i | i.refImmediateComposite() = platform)		--SET1
			->union(platform.getAllocationsInstances())														--SET2
			->union(UML!InstanceSpecification.allInstances()
				->select(i | platform.getAllocationsInstances()
								->collect(ai | ai.refImmediateComposite())
								->includes(i.refImmediateComposite()))										--SET3
			)->asSet();																						--Removes duplicates
			
		comments : Sequence(UML!Comment) = instances->collect(i | i.ownedComment)->flatten();
		instSystem : UML!InstanceSpecification = platform.ownedElement->first();
	} 
	to
		s : IM!Sistema (
			Name <- platform.name
		)
	do {
		--Filter out and categorize relevant CHESS elements
		thisModule.umlInstancesAll <- instances;
		thisModule.umlInstancesConnectors <- instances->select(i | i.classifier.isEmpty());
		thisModule.umlInstancesBlocks <- instances->select(i | not i.classifier.isEmpty());
		thisModule.umlAllocations <- MARTE!Assign.allInstances()->select(a | comments.includes(a.base_Comment));
		
		thisModule.umlInstancesBlocks <- thisModule.umlInstancesAll->select(i | thisModule.umlInstancesConnectors.excludes(i));
		thisModule.umlInstancesStereo <- thisModule.umlInstancesBlocks->select(i | i.getSBAStereotype() <> OclUndefined);

		--Instances that are relevant for the analysis are:
		--> Those that are constituents of the instance representing the target platform, plus
		--> Those that are constituents of the instances representing the platforms that own the instances involved in allocations
		thisModule.umlInstancesRelevant <- instSystem.findSBAConstituents()
												->union(platform.getAllocationsInstances()
															->collect(ai | ai.refImmediateComposite())
															->collect(im | im.ownedElement->first().findSBAConstituents()))->flatten();
			
		--Generate IM!Component elements, failure modes, and what can be done immediately
		for(i in thisModule.umlInstancesRelevant) {
			s.components <- s.components->including(
				thisModule.InstanceToComponent(i)
			);

			
			if(i.getSBAStereotype().oclType() = CHESS!SimpleStochasticBehavior) {
				thisModule.SimpleStochasticBehaviorToComponent(i);
			}else if(i.getSBAStereotype().oclType() = CHESS!FLABehavior){
				thisModule.FLASpecificationToComponent(i);
			}else if(i.getSBAStereotype().oclType() = CHESS!ErrorModelBehavior) {
				thisModule.ErrorModelToComponent(i);
			}
		}

		--Generate external faults
		for(i in thisModule.umlInstancesRelevant) {
			thisModule.PopulateExternalFaults(i);	
		}

		--Generate FGE, i.e., connect external faults
		for(i in thisModule.umlInstancesRelevant) {
			if(i.getSBAStereotype().oclType() = CHESS!SimpleStochasticBehavior) {
				thisModule.SimpleStochasticBehavior_FGE(i);
			}else if(i.getSBAStereotype().oclType() = CHESS!FLABehavior){
				thisModule.FLASpecification_FGE(i);
			}else if(i.getSBAStereotype().oclType() = CHESS!ErrorModelBehavior) {
				thisModule.ErrorModel_FGE(i);
			}
		}
		
		--Process allocations
		for(a in platform.getAllocations()) {
			thisModule.Allocation(a);
		}
		
		--Set FGE Backlinks
		for(fge in IM!FaultsGenerateErrors.allInstances()) {
			thisModule.setFGEBackLinks(fge.PropagationLogic, fge);	
		}
		--Set EPF Backlinks
		for(epf in IM!ErrorsProducesFailures.allInstances()) {
			thisModule.setEPFBackLinks(epf.PropagationLogic, epf);	
		}
		--Set IP Backlinks
		for(ip in IM!InternalPropagation.allInstances()) {
			thisModule.setIPBackLinks(ip.PropagationLogic, ip);	
		}

		--Process repair activities
		for(r in CHESS!Repair.allInstances()) {
			thisModule.RepairActivity(r);
		}
	}
}

unique lazy rule InstanceToComponent {
	from
		inst : UML!InstanceSpecification
	to 
		c : IM!Component (
			Name <- inst.name
		)		
}

--------------------------------------------------------------------
-- Rules to project component instances to IM!Component elements
--------------------------------------------------------------------

rule SimpleStochasticBehaviorToComponent(inst : UML!InstanceSpecification) {
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		st : CHESS!SimpleStochasticBehavior = inst.getSBAStereotype();
		tmpFailures : Set(TupleType(fm : String, p : Real)) = OclUndefined;
		tmpError : IM!Error = OclUndefined;
		tmpFailureMode : IM!FailureMode = OclUndefined;
		myFailureModes : String = if st.failureModesDistribution.oclIsUndefined() then '' else st.failureModesDistribution endif;
		eSeq : Sequence(IM!Error) = Sequence{};
		tmpFGE : IM!FaultsGenerateErrors = OclUndefined;
	}
	to
		fault : IM!InternalFault (
			Component <- c,
			Name <- inst.name + '_ift',
			PermanentProbability <- 1,
			Occurrence <- st.failureOccurrence.parseDistribution(),
			TransientDuration <- thisModule.Deterministic(0)
		)
	do {
		c.Faults = c.Faults.including(fault);
		
		for(p in inst.getPortSlots()
				->collect(sl | sl.definingFeature)
				->union(inst.classifier->first().ownedAttribute->select(op | op.oclIsKindOf(UML!Port)))
				->select(p | p.hasOutputFlow())->asSet()) {
			tmpFailures <- myFailureModes.parseFailureModesForPort(p.name);
				
			tmpError <- thisModule.AddError('e_' + p.name, c);
			eSeq <- eSeq.including(tmpError);
			for(fmSpec in tmpFailures) {
				thisModule.AddEPF(
					tmpError,
					thisModule.AddFailureMode(p.name + '.' + fmSpec.fm, c),
					thisModule.Deterministic(0),
					1,
					fmSpec.p
				);
			}
		}
		
		tmpFGE <- thisModule.AddFGE(Sequence{fault}, eSeq, thisModule.Deterministic(0), 1, 1);
		tmpFGE.PropagationLogic <- thisModule.FEXP_Fault(fault);
		tmpFGE.PropagationLogicStringFormat <- tmpFGE.PropagationLogic.toString();

		c.FaultsGeneratesErrors = c.FaultsGeneratesErrors.including(tmpFGE);
		
		if(not st.repairDelay.oclIsUndefined()) {
			if(st.repairDelay.trim().size() > 0) {
				thisModule.SimpleStochasticBehaviorRepair(inst);
			}
		}
	}
}
--This is called only if repairDelay is not empty
lazy rule SimpleStochasticBehaviorRepair {
	from  
		inst : UML!InstanceSpecification
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst); 		
	}
	to 
		repair : IM!RepairActivity (
			Target <- c,
			Name <- inst.name + '_repair',
			Duration <- inst.getSBAStereotype().repairDelay.parseDistribution(),
			SuccessProbability <- 1.0,
			When <- se
		),
		se : IM!ScheduleExpression
		(
			T <- si
		),
		si : IM!ScheduleExpressionImmediately
	do {
		se.EX <- thisModule.SCHEXP_FailureModesCollection(c.FailureModes);	
	}
}

rule FLASpecificationToComponent(inst : UML!InstanceSpecification) {
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		st : CHESS!FLABehavior = inst.getSBAStereotype();
		flaRules : Sequence(String) = st.fptc.regexReplaceAll('FLA:', ' ').trim().split(';');
		tmpLeft : String = OclUndefined;
		tmpRight : String = OclUndefined;
		tmpFailures : Sequence(String) = OclUndefined;
		errorMap : Map(String,IM!Error) = Map{};
		tmpError : IM!Error = OclUndefined;
		tmpEPF : IM!ErrorsProducesFailures = OclUndefined;
		fToPropagate : Sequence(IM!FailureMode) = Sequence{};
		j : Integer = 0;
	}
	
	do {
		--For every line of the FLA specification
		for(spec in flaRules) {
			j <- j+1;
			tmpError <- thisModule.AddError('e_'+j,c);
			
			tmpRight <- spec.trim().split('->')->last().trim();			--Get right hand side
			tmpFailures <- tmpRight.split(',');							--Get the different failures in the right hand side
			
			--For every failure in the right side of the rule
			fToPropagate <- Sequence{};
			for(failure in tmpFailures) {
				--If it is not the 'noFailure' element
				if(failure.indexOf('.' + thisModule.flaNoFailure) = -1) {
					--If the failure mode does not exist already
					if(not c.hasFailureMode(failure)) {
						thisModule.AddFailureMode(failure, c);
					}
					fToPropagate <- fToPropagate.including(
						c.FailureModes->select(f | f.localName = failure)->first()
					);
				}
			}
			
			--If the set of failure modes to propagate for this rule
			--is not empty, then create an EPF element
			if(not fToPropagate.isEmpty()) {
				tmpEPF <- thisModule.AddFLARuleEPF(tmpError);
				tmpEPF.Destination <- fToPropagate;
			}

		}
	}		
}

rule ErrorModelToComponent(inst : UML!InstanceSpecification) {
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		st : CHESS!ErrorModelBehavior = inst.getSBAStereotype();
		errorModel : CHESS!ErrorModel = st.errorModel->first();
		states : Sequence(UML!State) = errorModel.base_StateMachine.ownedElement->first().ownedElement->select(e | e.oclIsKindOf(UML!State));
		pseudo : Sequence(CHESS!Pseudostate) = errorModel.base_StateMachine.ownedElement->first().ownedElement->select(e | e.oclIsKindOf(CHESS!Pseudostate));
		transitions : Sequence(UML!Transition) = errorModel.base_StateMachine.ownedElement->first().ownedElement->select(e | e.oclIsKindOf(UML!Transition));
		tmpStereotype : OclAny = OclUndefined;
		tmpExternalFaults : String = OclUndefined;
	}
	do {	
		--Scan all CHESS!Failure elements in the error model,
		--to create the needed IM!FailureMode elements
		for(tr in transitions) {
			tmpStereotype <- tr.getFailureStereotype();
			if(not tmpStereotype.oclIsUndefined()) {
				for(f in tmpStereotype.mode) {
					--If it is not the 'noFailure' element
					if(f.indexOf('.' + thisModule.flaNoFailure) = -1) {
						--If the failure mode does not exist already
						if(not c.hasFailureMode(f)) {
							thisModule.AddFailureMode(f, c);
						}
					}
				}
			}
		}
		
		--Transform ErrorModel States
		for(s in states) {
			thisModule.ErrorModelStateToError(s,inst);
		}
		
		--Transform ErrorModel Pseudostates (choice)
		for(s in pseudo->select(p | p.kind = #choice)) {
			thisModule.ErrorModelStateToError(s,inst);
		}
		
		--Transform ErrorModel <<Failure>> Transitions
		for(tr in transitions) {
			tmpStereotype <- tr.getSBAStereotype();
			if(tmpStereotype.oclIsTypeOf(CHESS!Failure)) {		
				thisModule.AddEPFFromErrorModelFailure(tmpStereotype,inst);
			}
		}
				
		--<<InternalFault>> become IM!InternalFault
		for(tr in transitions) {
			tmpStereotype <- tr.getSBAStereotype();
			if(tmpStereotype.oclIsTypeOf(CHESS!InternalFault)) {
				thisModule.InternalFault(tmpStereotype,inst);
			}
		}
		
		--Transform ErrorModel <<InternalPropagation>> Transitions,
		--but only those for which the 'externalFaults' attribute is empty.
		--(for the others all the external faults need to be in place)
		for(tr in transitions) {
			tmpStereotype <- tr.getSBAStereotype();
			if(tmpStereotype.oclIsTypeOf(CHESS!InternalPropagation)) {
				if(tmpStereotype.oclIsTypeOf(CHESS!InternalFault)) {
					--Do nothing (processed elsewhere)				
				}else{
					--Match <<InternalPropagation>> stereotype only
					tmpExternalFaults <- tmpStereotype.externalFaults;
					if(tmpExternalFaults.oclIsUndefined()) {
						thisModule.InternalPropagation(tmpStereotype,inst);
					}
				}
			}
		}
	}
}

--------------------------------------------------------------------
-- Rule to generate external faults for component instances
--------------------------------------------------------------------

rule PopulateExternalFaults(inst : UML!InstanceSpecification) {
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		inPorts : Set(UML!Slot) = inst.getPortSlots()->select(p | p.hasInputFlow());
		faultName : String = OclUndefined;
		connPort : UML!Slot = OclUndefined;
		connComp : IM!Component = OclUndefined;
		tmpExternalFault : IM!ExternalFault = OclUndefined;
	}	
	do {
		for(p in inPorts) {
			--Find connected port
			connPort <- p.getSBAConnections()->first();
			--Find connected component (slot owner)
			if(not connPort.oclIsUndefined()) {
				connComp <- thisModule.InstanceToComponent(connPort.refImmediateComposite());
				for(f in connComp.FailureModes->select(fm | fm.getPortName() = connPort.name)) {
					faultName <- f.Name.split('\\.')->last();
					--If the external faults has not already been added then add it
					if(c.Faults->select(ft | ft.Name = connComp.Name + '_' + f)->isEmpty()) {				
						tmpExternalFault <- thisModule.AddExternalFault(p.name + '.' + faultName, inst);
						tmpExternalFault.Source <- f;
					}
				}
			}
		}
	}
}

--------------------------------------------------------------------
-- Rule to generate FGE elements
--------------------------------------------------------------------
rule SimpleStochasticBehavior_FGE(inst : UML!InstanceSpecification) {
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		fge : IM!FaultsGenerateErrors = OclUndefined;
		externals : Sequence(IM!Fault) = c.Faults->select(ft | ft.oclIsTypeOf(IM!ExternalFault));
	}
	do {		
		--FGE for external faults
		if(externals->size() > 0) {
			fge <- thisModule.AddFGE(externals, c.Errors, 'det(0)'.parseDistribution(), 1, 1);
			fge.PropagationLogic <- thisModule.FEXP_MultiOr(
				externals->collect(f | thisModule.FEXP_Fault(f))
			);
			fge.PropagationLogicStringFormat <- fge.PropagationLogic.toString();
		}
	}
}

rule FLASpecification_FGE(inst : UML!InstanceSpecification) {
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		st : CHESS!FLABehavior = inst.getSBAStereotype();
		flaRules : Sequence(String) = st.fptc.regexReplaceAll('FLA:', ' ').trim().split(';');
		tmpLeft : String = OclUndefined;
		tmpRight : String = OclUndefined;
		tmpFaults : Sequence(String) = OclUndefined;
		tmpError : IM!Error = OclUndefined;
		fExpression : IM!FaultsExpressionNode = OclUndefined;
		fSources : Set(IM!Fault) = Set{};
		selFaults : Sequence(String) = OclUndefined;
		tmpExpressions : Sequence(IM!FaultsExpressionNode) = Sequence{};
		j : Integer = 0;
		faultPort : String = OclUndefined;
		faultMode : String = OclUndefined;
		tmpFGE : IM!FaultsGenerateErrors = OclUndefined;
	}
	
	do {
		--For every line of the FLA specification
		for(spec in flaRules) {
			j <- j+1;
			tmpError <- c.Errors->select(e | e.localName = 'e_'+j);
			
			tmpLeft <- spec.trim().split('->')->first().trim();			--Get right hand side
			tmpFaults <- tmpLeft.split(',');							--Get the different failures in the right hand side
			
			--For every fault in the left side of the rule
			tmpExpressions <- Sequence{};
			for(fault in tmpFaults) {
				faultPort <- fault.split('\\.')->first();
				faultMode <- fault.split('\\.')->last();
								
				if(faultMode = thisModule.flaNoFailure) {
					selFaults <- c.Faults->select(ft | ft.getPortName() = faultPort);
					fExpression <- thisModule.FEXP_MultiOr(
						selFaults->collect(f | thisModule.FEXP_Fault(f))
					);
					fExpression <- thisModule.FEXP_Not(fExpression);
				}else if(faultMode = thisModule.flaWildcard) {
					selFaults <- c.Faults->select(ft | ft.getPortName() = faultPort); 
					fExpression <- thisModule.FEXP_MultiOr(
						selFaults->collect(f | thisModule.FEXP_Fault(f))
					);
				}else{
					selFaults <- c.Faults->select(ft | ft.localName = fault);
					fExpression <- thisModule.FEXP_Fault(
						selFaults->first()
					);
				}
				tmpExpressions <- tmpExpressions->append(fExpression);
			}
			fExpression <- thisModule.FEXP_MultiAnd(tmpExpressions);
			
			tmpFGE <- thisModule.AddFGE(selFaults, tmpError, 'det(0)'.parseDistribution(), 1, 1);
			fExpression.faultsGenerateErrors <- tmpFGE;
			tmpFGE.PropagationLogic <- fExpression;
			tmpFGE.PropagationLogicStringFormat <- fExpression.toString();
		}
	}		
}

rule ErrorModel_FGE(inst : UML!InstanceSpecification) {
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		st : CHESS!ErrorModelBehavior = inst.getSBAStereotype();
		errorModel : CHESS!ErrorModel = st.errorModel->first();
		states : Sequence(UML!State) = errorModel.base_StateMachine.ownedElement->first().ownedElement->select(e | e.oclIsKindOf(UML!State));
		pseudo : Sequence(CHESS!Pseudostate) = errorModel.base_StateMachine.ownedElement->first().ownedElement->select(e | e.oclIsKindOf(CHESS!Pseudostate));
		transitions : Sequence(UML!Transition) = errorModel.base_StateMachine.ownedElement->first().ownedElement->select(e | e.oclIsKindOf(UML!Transition));
		tmpStereotype : OclAny = OclUndefined;
		tmpExternalFaults : String = OclUndefined;
		tmpFGE : IM!FaultsGenerateErrors = OclUndefined;
		tmpIP : IM!InternalPropagation = OclUndefined;
		tmpFEXP : IM!FaultsExpressionNode = OclUndefined;
		tmpEEXP : IM!ErrorsExpressionNode = OclUndefined;
	}
	do {
		--Transform ErrorModel <<InternalPropagation>> Transitions,
		--for which the 'externalFaults' attribute is *not* empty.
		--(the others have been processed previously in rule ErrorModelToComponent)
		for(tr in transitions) {
			tmpStereotype <- tr.getSBAStereotype();
			if(tmpStereotype.oclIsTypeOf(CHESS!InternalPropagation)) {
				if(tmpStereotype.oclIsTypeOf(CHESS!InternalFault)) {
					--Do nothing (processed elsewhere)				
				}else{
					--Match <<InternalPropagation>> stereotype only
					if(tmpStereotype.externalFaults.oclIsUndefined()) {
						--Do nothing (processed elsewhere)
					}else{
						--Process InternalPropagation that have a value
						--in the externalFaults attribute
						--Set a default for the delay and weight
						if(tmpStereotype.delay.oclIsUndefined()) {
							tmpStereotype.delay <- 'det(0)';	
						}
						if(tmpStereotype.weight.oclIsUndefined()) {
							tmpStereotype.weight <- '1';	
						}
						
						if(tr.source.isInitialState()) {
							tmpExternalFaults <- tmpStereotype.externalFaults;
							tmpFEXP <- thisModule.FEXP_ParseString(tmpExternalFaults, inst);
							tmpFGE <- thisModule.AddFGE(
								tmpFEXP.faultsList(),
								thisModule.errmodErrorMap->get(Tuple{e=tr.target, cc=c}),
								tmpStereotype.delay.parseDistribution(),
								1,
								tmpStereotype.weight.toReal()
							);
							tmpFEXP.faultsGenerateErrors <- tmpFGE;
							tmpFGE.PropagationLogic <- tmpFEXP;
							tmpFGE.PropagationLogicStringFormat <- tmpFEXP.toString();
						}
						else{
							thisModule.InternalPropagation(tmpStereotype,inst);
						}
					}
				}
			}
		}
	}
}


lazy rule AddExternalFault {
	from
		fault : String,
		inst : UML!InstanceSpecification
	to 
		xft : IM!ExternalFault (
			Component <- thisModule.InstanceToComponent(inst),
			Name <- inst.name + '_xft_' + fault
		)
}

lazy rule ErrorModelStateToError {
	from 
		state : UML!Vertex,
		inst : UML!InstanceSpecification
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
	}
	to
		err : IM!Error (
			Name <- inst.name + '_' + state.name,
			Component <- c
		)
	do {
		thisModule.errmodErrorMap <- thisModule.errmodErrorMap->including(Tuple{e=state, cc=c}, err);
	}
}

lazy rule InternalFault {
	from
		chIntFault : CHESS!InternalFault,
		inst : UML!InstanceSpecification
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);		
	}
	to
		ift : IM!InternalFault (
			Name <- c.Name + '_ift_' + (c.Faults->select(f | f.oclIsKindOf(IM!InternalFault))->size()+1),
			Occurrence <- chIntFault.occurrence.parseDistribution(),
			PermanentProbability <- 1,
			Component <- c,
			TransientDuration <- thisModule.Deterministic(0)
		),
		fge : IM!FaultsGenerateErrors (
			Name <- c.Name + '_fge_' + (c.FaultsGeneratesErrors->size()+1),
			Component <- c,
			Source <- Sequence{ift},
			Destination <- thisModule.errmodErrorMap->get(Tuple{e=chIntFault.base_Transition.target, cc=c}),
			Weight <- 1,
			PropagationProbability <- 1,
			ActivationDelay <- thisModule.Deterministic(0),
			PropagationLogic <- thisModule.FEXP_Fault(ift),
			PropagationLogicStringFormat <- fge.PropagationLogic.toString()
		)
	do {
		--Workaround for the DEEM simulator crashing when InternalFaults
		--with zero delay are present in the model
		if(ift.Occurrence.oclIsTypeOf(IM!Deterministic)) {
			if(ift.Occurrence.Value = 0) {
				ift.Occurrence.Value <- '1e-100'.toReal();
			}
		}
	}
}

lazy rule InternalPropagation {
	from 
		chIntProp : CHESS!InternalPropagation,
		inst : UML!InstanceSpecification
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		myDelay : String = if chIntProp.delay.oclIsUndefined() then 'det(0)' else chIntProp.delay endif;
		myWeight : Real = if chIntProp.weight.oclIsUndefined() then 1 else chIntProp.weight.toReal() endif;
	}
	to
		imIntProp : IM!InternalPropagation (
			Component <- c,
			Name <- c.Name + '_intprop_' + (c.InternalPropagation->size()+1),
			Source <- Sequence{thisModule.errmodErrorMap->get(Tuple{e=chIntProp.base_Transition.source, cc=c})},
			Destination <- Sequence{thisModule.errmodErrorMap->get(Tuple{e=chIntProp.base_Transition.target, cc=c})},
			PropagationProbability <- 1,
			PropagationDelay <- myDelay.parseDistribution(),
			Weight <- myWeight,
			PropagationLogic <- thisModule.EEXP_Error(imIntProp.Source->first()),
			PropagationLogicStringFormat <- imIntProp.PropagationLogic.toString(),
			FaultGuard <- thisModule.FEXP_ParseString(chIntProp.externalFaults, inst)
		)
}

rule AddFailureMode(name : String, c : IM!Component) {
	to 
		fm : IM!FailureMode (
			Name <- c.Name + '_' + name
		)
	do {
		c.FailureModes <- c.FailureModes->append(fm);
	
		fm;
	}
}

rule AddError(name : String, c : IM!Component) {
	to
		e : IM!Error (
			Name <- c.Name + '_' + name,
			Component <- c
		)
	do {
		e;
	}
}

lazy rule AddEPFFromErrorModelFailure {
	from
		f : CHESS!Failure,
		inst : UML!InstanceSpecification
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		eSource : IM!Error = thisModule.errmodErrorMap->get(Tuple{e=f.base_Transition.source, cc=c});
		myDelay : String = if f.delay.oclIsUndefined() then 'det(0)' else f.delay endif;
		myWeight : Real = if f.weight.oclIsUndefined() then 1 else f.weight.toReal() endif;
	}
	to
		epf : IM!ErrorsProducesFailures (
			Name <- c.Name + '_epf_' + (c.ErrorsGeneratesFailures->size()+1),
			Source <- Sequence{eSource},
			Destination <- c.FailureModes->select(fm | f.mode->includes(fm.localName)),
			Component <- c,
			PropagationDelay <- myDelay.parseDistribution(),
			PropagationProbability <- 1,
			Weight <- myWeight,
			PropagationLogic <- thisModule.EEXP_Error(eSource),
			PropagationLogicStringFormat <- epf.PropagationLogic.toString() 
		)
	do {
		epf;
	}	
}

rule AddFLARuleEPF(e : IM!Error) {
	to
		epf : IM!ErrorsProducesFailures (
			Name <- e.Name + '_epf',
			Source <- Sequence{e},
			Destination <- Sequence{},
			Component <- e.Component,
			PropagationDelay <- thisModule.Deterministic(0),
			PropagationProbability <- 1,
			Weight <- 1,
			PropagationLogic <- thisModule.EEXP_Error(e),
			PropagationLogicStringFormat <- epf.PropagationLogic.toString()
		)
	do{
		epf;
	}
}

rule AddFGE(f : Sequence(IM!Fault), e : Sequence(IM!Error), delay : IM!Distribution, p : Real, weight : Real) {
	using {
		c : IM!Component = f->first().Component;
	}
	to
		fge : IM!FaultsGenerateErrors (
			Name <- c.Name + '_fge_' + (c.FaultsGeneratesErrors->size()+1),
			Component <- c,
			Source <- f,
			Destination <- e,
			ActivationDelay <- delay,
			PropagationProbability <- p,
			Weight <- weight
		)
	do {
		fge;	
	}
}

rule AddEPF(e : IM!Error, fm : IM!FailureMode, delay : IM!Distribution, p : Real, weight : Real) {
	using {
		c : IM!Component = fm.Component;			
	}
	to 
		epf : IM!ErrorsProducesFailures (
			Name <- c.Name + '_epf_' + (c.ErrorsGeneratesFailures->size()+1),
			Component <- c,
			Source <- Set{e},
			Destination <- Set{fm},
			PropagationDelay <- delay,
			PropagationProbability <- p,
			Weight <- weight,
			PropagationLogic <- thisModule.EEXP_Error(e),
			PropagationLogicStringFormat <- epf.PropagationLogic.toString()
		)
}

rule AddSourceError(fm : IM!FailureMode) {
	using {
		c : IM!Component = fm.Component;
	}
	to 
		e : IM!Error (
			Name <- c.Name + '_e_' + fm.Name,
			Component <- c
		),
		epf : IM!ErrorsProducesFailures (
			Source <- Set{e},
			Destination <- Set{fm},
			Component <- c,
			PropagationLogic <- thisModule.EEXP_Error(e),
			PropagationLogicStringFormat <- epf.PropagationLogic.toString()
		)
}

--------------------------------------------------------------------
-- Rules related to the definition of the metric
--------------------------------------------------------------------

lazy rule newEvalIntervalOfTime {
	from
		t : Real
	to
		iot : IM!IntervalOfTimeAveraged
		(
			begin <- 0,
			end <- t
		)
}
lazy rule newEvalInstantOfTime {
	from
		t : Real
	to
		instant : IM!InstantOfTime ( timePoint <- t )
}

--Find target failure modes to be considered based on the attributes
--of the StateBasedAnalysis stereotype.
rule FindTargetFailureModes(sba : CHESS!StateBasedAnalysis) {
	using {
		targets : Set(UML!InstanceSpecification) = Set{};
		targetSlots : Set(UML!Slot) = Set{};
		fmSelected : Set(IM!FailureMode) = Set{};
	}
	do {
		--Find target components based on two attributes
		-->platform
		-->targetDepComponent
		if(sba.targetDepComponent.isEmpty()) {
			targets <- sba.platform->collect(p | p.base_Package.ownedMember->first())->flatten();
		}else{
			targets <- sba.targetDepComponent;
		}
		
		
		--Find ports of target components having an output dataflow
		targetSlots <- targets->collect(i | i.getPortSlots())
								->flatten()
								->select(sl | sl.hasOutputFlow());
	
		--Filter ports based on 'targetPort', if set
		if(not sba.targetPort.isEmpty()) {
			targetSlots <- sba.targetPort.asSet()->intersection(targetSlots);
		}
	
		--Process possibly existing downward delegations
		targetSlots <- targetSlots->collect(sl | sl.getSBADelegationsDownwards())->flatten();
		
		--Find all failure modes related to the selected ports
		fmSelected <-
			 targetSlots->collect(sl | thisModule.InstanceToComponent(sl.refImmediateComposite()).FailureModes->select(fm | fm.getPortName() = sl.name))
						->flatten()->asSet();

		--Filter failure modes based on 'targetFailureMode', if set
		if(not sba.targetFailureMode->isEmpty()) {
			fmSelected <-
				fmSelected->select(fm | sba.targetFailureMode->contains(fm.getModeName()));
		}

		fmSelected;	
	}
}

rule Reliability(sba : CHESS!StateBasedAnalysis, time : Real){

	using {
		strClean : String = sba.measure.regexReplaceAll('[={}()]', ' ').trim();
		iInstant : Integer = strClean.indexOf('instantOfTime');

					
		imsistema : IM!Sistema = IM!Sistema.allInstances()->first();
	}
	to
		re : IM!Reliability (
			Name <-	sba.base_NamedElement.name,
			target <- thisModule.FindTargetFailureModes(sba)
		)

	do{
		imsistema.measures.add(re);
		if (iInstant > 0) {
			re.evaluations.add(
				thisModule.newEvalInstantOfTime(
					strClean.substring(iInstant + 1 + 'instantOfTime'.size(), strClean.size()).toReal()
				)
			);
		}
		else{
			--Should not happen!
		}
	}
}

rule Availability(sba : CHESS!StateBasedAnalysis) {
	using {
		strClean : String = sba.measure.regexReplaceAll('[={}()]', ' ').trim();
		iInterval : Integer = strClean.indexOf('intervalEnd');
		iInstant : Integer = strClean.indexOf('instantOfTime');

		imsistema : IM!Sistema = IM!Sistema.allInstances()->first();
	}
	to
		re : IM!Availability (
			Name <-	sba.base_NamedElement.name,
			target <- thisModule.FindTargetFailureModes(sba)
		)
	do{
		imsistema.measures.add(re);

		if (iInterval > 0) {
			re.evaluations.add(
				thisModule.newEvalIntervalOfTime(
					strClean.substring(iInterval + 1 + 'intervalEnd'.size(), strClean.size()).toReal()
				)
			);
		}
		else if (iInstant > 0) {
			re.evaluations.add(
				thisModule.newEvalInstantOfTime(
					strClean.substring(iInstant + 1 + 'instantOfTime'.size(), strClean.size()).toReal()
				)
			);
		}
		else{
			--Should not happen!
		}
	}
}

rule PFD(sba : CHESS!StateBasedAnalysis) {
	using {
		strClean : String = sba.measure.regexReplaceAll('[={}()]', ' ').trim();

		imsistema : IM!Sistema = IM!Sistema.allInstances()->first();
	}
	to
		pfd : IM!FailureProbability (
			Name <-	sba.base_NamedElement.name,
			target <- thisModule.FindTargetFailureModes(sba)
		)

	do{
		imsistema.measures.add(pfd);
		
		pfd.evaluations.add(
			thisModule.newEvalInstantOfTime(
				strClean.regexReplaceAll('PFD', ' ').trim().toReal()
			)
		);
	}
}

--------------------------------------------------------------------
-- Rules to create IM!Distribution elements
--------------------------------------------------------------------
lazy rule Exponential {
	from
		lambda : Real
	to
		e : IM!Exponential ( Rate <- lambda )
}

lazy rule Deterministic {
	from
		value : Real
	to
		d : IM!Deterministic ( Value <- value )
}

lazy rule Uniform {
	from
		lower : Real,
		upper : Real
	to
		d : IM!Uniform ( 
			Lower <- lower,
			Upper <- upper
		)
}

lazy rule Gaussian {
	from
		mean : Real,
		variance : Real
	to 
		g : IM!Gaussian (
			Mean <- mean,
			Variance <- variance
		)
}

lazy rule Gamma {
	from
		a : Real,
		b : Real
	to 
		g : IM!Gamma (
			Alpha <- a,
			Beta <- b
		)
}

lazy rule Weibull {
	from
		a : Real,
		b : Real
	to 
		g : IM!Weibull (
			Alpha <- a,
			Beta <- b
		)
}

--------------------------------------------------------------------
-- Rules to build Faults/Errors expressions
--------------------------------------------------------------------
rule FEXP_Fault(f: IM!Fault) {
	to
		fefn : IM!FaultsExpressionFaultNode (
			Fault <- f
		)
	do{
		fefn;
	}
}

rule FEXP_Or(e1 : IM!FaultsExpressionNode, e2: IM!FaultsExpressionNode) {
	to
		feon : IM!FaultsExpressionOrNode (
			FaultsExpression1 <- e1,
			FaultsExpression2 <- e2
		)
	do{
		feon;
	}
}

rule FEXP_And(e1 : IM!FaultsExpressionNode, e2: IM!FaultsExpressionNode) {
	to
		fean : IM!FaultsExpressionAndNode (
			FaultsExpression1 <- e1,
			FaultsExpression2 <- e2
		)
	do{
		fean;
	}
}

rule FEXP_Not(e : IM!FaultsExpressionNode) {
	to 
		fenn : IM!FaultsExpressionNotNode (
			FaultsExpression <- e	
		)
	do {
		fenn;
	}
}

rule FEXP_MultiOr(fe : Sequence(IM!FaultsExpressionNode)) {
	using {
		tmpExpression1 : IM!FaultsExpressionNode = OclUndefined;
		tmpExpression2 : IM!FaultsExpressionNode = OclUndefined;
		tmpSequence : Sequence(IM!Fault) = fe;
	}
	do {
		if(fe->size() = 1) {
			tmpExpression1 <- fe->first();
		}else{
			tmpExpression1 <- tmpSequence->first();
			tmpSequence <- tmpSequence.subSequence(2, tmpSequence.size());
			tmpExpression2 <- tmpSequence->first();
			tmpSequence <- tmpSequence.subSequence(2, tmpSequence.size());
			
			tmpExpression1 <- thisModule.FEXP_Or(tmpExpression1,tmpExpression2);
			for(ft in tmpSequence) {
				tmpExpression2 <- 	thisModule.FEXP_Or(
										tmpExpression1,
										ft
								 	);
				tmpExpression1 <- tmpExpression2;
			}
		}
		
		tmpExpression1;
	}	
}

rule FEXP_MultiAnd(fe : Sequence(IM!FaultsExpressionNode)) {
	using {
		tmpExpression1 : IM!FaultsExpressionNode = OclUndefined;
		tmpExpression2 : IM!FaultsExpressionNode = OclUndefined;
		tmpSequence : Sequence(IM!Fault) = fe;
	}
	do {
		if(fe->size() = 1) {
			tmpExpression1 <- fe->first();
		}else{
			tmpExpression1 <- tmpSequence->first();
			tmpSequence <- tmpSequence.subSequence(2, tmpSequence.size());
			tmpExpression2 <- tmpSequence->first();
			tmpSequence <- tmpSequence.subSequence(2, tmpSequence.size());
			
			tmpExpression1 <- thisModule.FEXP_And(tmpExpression1,tmpExpression2);
			for(ft in tmpSequence) {
				tmpExpression2 <- 	thisModule.FEXP_And(
										tmpExpression1,
										ft
								 	);
				tmpExpression1 <- tmpExpression2;
			}
		}
		
		tmpExpression1;
	}	
}

rule EEXP_Error(e: IM!Error) {
	to
		eeen : IM!ErrorsExpressionErrorNode (
			Error <- e
		)
	do{
		eeen;
	}
}

--Parses a string into a FaultsExpression
---TODO: Implement more advanced parsing
rule FEXP_ParseString(exp : String, inst : UML!InstanceSpecification) {
	using {
		c : IM!Component = thisModule.InstanceToComponent(inst);
		tmpSplit : Sequence(String) = OclUndefined;
		expRet : IM!FaultsExpressionNode = OclUndefined;
	}
	do {
		if(not exp.oclIsUndefined()) {
			tmpSplit <- exp.split(' and | AND ');
			if(tmpSplit.size() > 1) {
				expRet <-
				thisModule.FEXP_MultiAnd(
					tmpSplit->collect(
						ft | c.Faults->select(ff | ff.localName = ft.trim())->first()
					)->
					flatten()->
					collect(ft | thisModule.FEXP_Fault(ft))
				);
			}else {
				tmpSplit <- exp.split(' or | OR ');
				if(tmpSplit.size() > 1) {
					expRet <-
					thisModule.FEXP_MultiOr(
						tmpSplit->collect(
							s | c.Faults->select(ft | ft.localName = s.trim())
						)->
						flatten()->
						collect(ft | thisModule.FEXP_Fault(ft))
					);
				}else {
					expRet <- thisModule.FEXP_Fault(tmpSplit->first());
				}
			}
		}
		
		expRet;
	}
}

rule setFGEBackLinks(fen: IM!FaultsExpressionNode, fge: IM!FaultsGenerateErrors ) {
	do {
		fen.faultsGenerateErrors <- fge;
		if (fen.oclIsTypeOf(IM!FaultsExpressionOrNode)) {
			thisModule.setFGEBackLinks(fen.FaultsExpression1, fge);
			thisModule.setFGEBackLinks(fen.FaultsExpression2, fge);
		}else if (fen.oclIsTypeOf(IM!FaultsExpressionAndNode)){
			thisModule.setFGEBackLinks(fen.FaultsExpression1, fge);
			thisModule.setFGEBackLinks(fen.FaultsExpression2, fge);
		}else if (fen.oclIsTypeOf(IM!FaultsExpressionNotNode)) {
			thisModule.setFGEBackLinks(fen.FaultsExpression, fge);
		}
	}
}

rule setEPFBackLinks(een: IM!ErrorsExpressionNode, epf: IM!ErrorsProducesFailures ) {
	do {
		een.errorPropagation <- epf;
	}
}

rule setIPBackLinks(een: IM!ErrorsExpressionNode, ip: IM!InternalPropagation ) {
	do {
		een.errorPropagation <- ip;
	}
}


--Rule for Repair activities
unique lazy rule RepairActivity {
	from
		r : CHESS!Repair
	to
		act : IM!RepairActivity
		(
			Name <- r.base_Activity.name,
			SuccessProbability <- r.probSuccess.toReal(),
			Duration <- r.duration.parseDistribution(),
			When <- timeexp
		),
		timeexp : IM!ScheduleExpression
		(
				T <-
				if r.when.trim().startsWith('Periodic') then
					thisModule.SCHEXP_Periodic(r.when)
				else
					if r.when.trim().startsWith('AtTime') then
						thisModule.SCHEXP_AtTime(r.when)
					else
						OclUndefined
					endif
				endif,
				EX <- timeexp_ex
		),
		timeexp_ex : IM!ScheduleExpressionTrue
	do {
		act.Target <- UML!Slot.allInstances()
						->select(sl | r.targets->includes(sl.definingFeature))
						->collect(sl | sl.value->first().instance)
						->select(i | thisModule.umlInstancesRelevant->includes(i))
						->collect(i | thisModule.InstanceToComponent(i));
	}
}

--Rule for ErrorDetection activities
unique lazy rule ErrorDetectionActivity {
	from
		r : CHESS!ErrorDetection
	to
		act : IM!DetectionActivity
		(
			Name <- r.base_Activity.name,
			Coverage <- r.probSuccess.toReal(),
			Duration <- r.duration.parseDistribution(),
			When <- timeexp
		),
		timeexp : IM!ScheduleExpression
		(
				T <-
				if r.when.trim().startsWith('Periodic') then
					thisModule.SCHEXP_Periodic(r.when)
				else
					if r.when.trim().startsWith('AtTime') then
						thisModule.SCHEXP_AtTime(r.when)
					else
						OclUndefined
					endif
				endif,
				EX <- timeexp_ex
		),
		timeexp_ex : IM!ScheduleExpressionTrue
	do {
		act.Target <- UML!Slot.allInstances()
						->select(sl | r.targets->includes(sl.definingFeature))
						->collect(sl | sl.value->first().instance)
						->collect(i | thisModule.InstanceToComponent(i));
	}
}

--rule RepairActivity(r : IM!RepairActivity){
--
--	to
--		se : IM!ScheduleExpression
--		(
--			T <- si
--		),
--		si : IM!ScheduleExpressionImmediately
--	do{
--		r.When <- se;
--		for (c in r.Target){
--			for(fm in c.FailureModes) {
--				thisModule.SchedCond(fm);
--			}
--		}
--		if (thisModule.TempScen->size() = 1){
--			se.EX <- thisModule.TempScen->first();
--		}else{
--			for(scen in thisModule.TempScen){
--				if (scen <> thisModule.TempScen->last()){
--					thisModule.CreateScenOrExpr();
--				}
--			}
--			thisModule.TempScen->addAll(thisModule.TempScenSeq);
--
--			for(scen in thisModule.TempScen){
--				if (scen.oclIsTypeOf(IM!ScheduleExpressionOr)){
--					scen.e1 <- thisModule.TempScen.at(thisModule.Counter);
--					thisModule.Counter <- thisModule.Counter+1;
--					scen.e2 <- thisModule.TempScen.at(thisModule.Counter);
--					thisModule.Counter <- thisModule.Counter+1;
--				}
--			}
--			se.EX <- thisModule.TempScen->last();
--		}
--
--		thisModule.TempScen.clear();
--		thisModule.TempScenSeq.clear();
--		thisModule.Counter <- 1;
--	}
--}

rule SchedCond(fm : IM!FailureMode){

	to
		scefn : IM!ScheduleExpressionFailed (
			failureMode <- fm
		)

	do{
		thisModule.TempScen.add(scefn);
	}
}

rule CreateScenOrExpr(){

	to
		sceon : IM!ScheduleExpressionOr

	do{
		thisModule.TempScenSeq.add(sceon);
	}

}

--------------------------------------------------------------------
-- Rules to generate ScheduleExpression elements
--------------------------------------------------------------------

lazy rule SCHEXP_Periodic {
	from
		s : String
	using {
		sClean : String = s.regexReplaceAll('[={}()]', ' ').trim();
	}
	to
		p : IM!ScheduleExpressionPeriodic
		(
			PeriodDuration <- d
		),
		d : IM!Deterministic
		(
			Value <- sClean.substring('Periodic'.size()+1, sClean.size()).toReal()
		)
}
lazy rule SCHEXP_AtTime {
	from
		s : String
	using {
		sClean : String = s.regexReplaceAll('[={}()]', ' ').trim();
	}
	to
		p : IM!ScheduleExpressionAtTime
		(
			t <- sClean.substring('AtTime'.size()+1, sClean.size()).toReal()
		)
}

rule SCHEXP_Or(exp1 : IM!ScheduleExpressionCond, exp2 : IM!ScheduleExpressionCond) {
	to 
		e : IM!ScheduleExpressionOr
		(
			e1 <- exp1,
			e2 <- exp2			
		)
	do {
		e;
	}
}

rule SCHEXP_And(exp1 : IM!ScheduleExpressionCond, exp2 : IM!ScheduleExpressionCond) {
	to 
		e : IM!ScheduleExpressionAnd
		(
			e1 <- exp1,
			e2 <- exp2			
		)
	do {
		e;
	}
}

rule SCHEXP_FailureMode(fm : IM!FailureMode) {
	to
		e : IM!ScheduleExpressionFailed
		(
			failureMode <- fm			
		)
	do {
		e;
	}
}

rule SCHEXP_MultiOr(schSeq : Set(IM!ScheduleExpressionCond)) {
	using {
		tmpExpression1 : IM!ScheduleExpressionCond = OclUndefined;
		tmpExpression2 : IM!ScheduleExpressionCond = OclUndefined;
		tmpSequence : Sequence(IM!ScheduleExpressionCond) = schSeq;
	}
	do {
		if(schSeq->size() = 1) {
			tmpExpression1 <- schSeq->first();
		}else{
			tmpExpression1 <- tmpSequence->first();
			tmpSequence <- tmpSequence.subSequence(2, tmpSequence.size());
--			tmpExpression2 <- tmpSequence->first();
--			tmpSequence <- tmpSequence.subSequence(2, tmpSequence.size());
--			
--			tmpExpression1 <- thisModule.SCHEXP_Or(tmpExpression1,tmpExpression2);
			
			for(ee in tmpSequence) {
				tmpExpression2 <- 	thisModule.SCHEXP_Or(
										tmpExpression1,
										ee
								 	);
				tmpExpression1 <- tmpExpression2;
			}
		}
		
		tmpExpression1;
	}	
}

rule SCHEXP_FailureModesCollection(fms : Set(IM!FailureMode)) {
	using {
		tmp : IM!ScheduleExpressionCondition = OclUndefined;
	}
	do {
		tmp <-
			thisModule.SCHEXP_MultiOr(
				fms->collect(fm | thisModule.SCHEXP_FailureMode(fm))
			);

		tmp;
	}
}

--------------------------------------------------------------------
-- Rules for allocation
--------------------------------------------------------------------
rule Allocation(a : MARTE!Assign) {
	using {
		tmpXFT : IM!ExternalFault = OclUndefined;
	}
	do {
		for(instFrom in a.from) {
			for(instTo in a.to) {
				for(fm in thisModule.InstanceToComponent(instTo).FailureModes) {			
					tmpXFT <- thisModule.AddExternalFault(fm.getModeName(), instFrom);
					tmpXFT.Source <- fm;
					tmpXFT.Name <- instFrom.name + '_allocation_' + fm.Name;
				}				
			}
		}
	}
}
--rule Assign (a : MARTE!Assign){
--
--	do{
--		--"from" and "to" are keywords in ATL... (works anyway, only issue: they are highlighted)
--		thisModule.Instances.addAll(a.from);
----		thisModule.Components.addAll(a.to->collect(f | f.classifier->first()));
--
--		--get also connectors from the allocated HW/SW
--		for (f in a.from){
--			thisModule.Connectors.addAll(f.owner.getConnectors);
--		}
--		for (t in a.to){
--			thisModule.Connectors.addAll(t.owner.getConnectors);
--		}
--
--		--finally get ports from the allocated HW/SW
--		for (f in a.from){
--			for (i in f.owner.getInstances){
--				thisModule.Ports.addAll(i.slot->collect(d | d.definingFeature));
--			}
--		}
--		for (t in a.to){
--			for (i in t.owner.getInstances){
--				thisModule.Ports.addAll(i.slot->collect(d | d.definingFeature));
--			}
--		}
--	}
--}

--Find allocation specifications related to a given platform
helper context UML!Package def : getAllocations() : Set(MARTE!Assign) =
	MARTE!Assign.allInstances()->select(a | a.base_Comment.owner = self.ownedElement->first().classifier->first());

--Find instances involved in allocations related to a given platform
helper context UML!Package def: getAllocationsInstances() : Set(UML!InstanceSpecification) =
	self.getAllocations()->collect(a | a.from->union(a.to))->flatten();	

--Check if a IM!Component already contains a specific failure mode
helper context IM!Component def: hasFailureMode(fm : String) : Boolean =
	not self.FailureModes->select(f | f.localName.trim() = fm.trim())->isEmpty();

--Check if a IM!Component already contains a specific fault
helper context IM!Component def: hasFault(fm : String) : Boolean =
	not self.Faults->select(f | f.localName.trim() = fm.trim())->isEmpty();

--Get <<Failure>> stereotype from a Transition
helper context UML!Transition def: getFailureStereotype() : CHESS!Failure =
	CHESS!Failure.allInstances()->select(f | f.base_Transition = self)->first();

--Get <<ErrorState>> stereotype from a State
helper context UML!State def: getErrorStateStereotype() : CHESS!ErrorState =
	CHESS!ErrorState.allInstances()->select(e | e.base_State = self)->first();

--Check if a Vertex is an initial state (healty state of the error model)
helper context UML!Vertex def: isInitialState() : Boolean =
	if(self.oclIsKindOf(CHESS!Pseudostate)) then
		self.kind = #initial
	else
		false
	endif;

--Remove the component name
helper context String def: noNamespace(n : String) : String =
	self.regexReplaceAll(n + '_', '');
helper context IM!Fault def: localName : String =
	let fClean : String = self.Name.noNamespace(self.Component.Name)
	in fClean.substring(5, fClean.size());	--Removes the initial xft_ or ift_ prefix
helper context IM!Error def: localName : String =
	self.Name.noNamespace(self.Component.Name);
helper context IM!FailureMode def: localName : String =
	self.Name.noNamespace(self.Component.Name);
helper context IM!Threat def: fullName : String = self.Name;

--Get info on a IM!Fault and IM!FailureMode
helper context IM!Fault def: getPortName() : String =
	self.localName.split('\\.').at(1);
helper context IM!Fault def: getModeName() : String =
	self.localName.split('\\.').at(2);
helper context IM!FailureMode def: getPortName() : String =
	self.localName->split('\\.')->at(1);
helper context IM!FailureMode def: getModeName() : String =
	self.localName.split('\\.').at(2);


--------------------------------------------------------------------
-- Parse strings in VSL notation into IM!Distribution elements
--------------------------------------------------------------------
helper context String def: parseDistribution() : IM!Distribution = 
	let dist : String = self.trim().toLower() in
	if dist.startsWith('exp') then
		dist.parseExponential()
	else if dist.startsWith('det') then
		dist.parseDeterministic()
	else if dist.startsWith('uni') then
		dist.parseUniform()
	else if dist.startsWith('norm') or dist.startsWith('gauss') then
		dist.parseGaussian()
	else if dist.startsWith('gam') then
		dist.parseGamma()
	else if dist.startsWith('wei') then
		dist.parseWeibull()
	else
		thisModule.Exponential(0)
	endif endif endif endif endif endif;

helper context String def: parseExponential() : IM!Exponential =
	thisModule.Exponential(self.substring(self.indexOf('(')+2, self.indexOf(')')).toReal());

helper context String def: parseDeterministic() : IM!Deterministic =
	thisModule.Deterministic(self.substring(self.indexOf('(')+2, self.indexOf(')')).toReal());

helper context String def: parseUniform() : IM!Uniform =
	let iComma : Integer = self.indexOf(',') in
	thisModule.Uniform(
		self.substring(self.indexOf('(')+2, iComma).toReal(),
		self.substring(iComma+2, self.indexOf(')')).toReal()
	);

helper context String def: parseGaussian() : IM!Gaussian =
	let iComma : Integer = self.indexOf(',') in
	thisModule.Gaussian(
		self.substring(self.indexOf('(')+2, iComma).toReal(),
		self.substring(iComma+2, self.indexOf(')')).toReal()
	);

helper context String def: parseGamma() : IM!Gamma =
	let iComma : Integer = self.indexOf(',') in
	thisModule.Gamma(
		self.substring(self.indexOf('(')+2, iComma).toReal(),
		self.substring(iComma+2, self.indexOf(')')).toReal()
	);

helper context String def: parseWeibull() : IM!Gamma =
	let iComma : Integer = self.indexOf(',') in
	thisModule.Weibull(
		self.substring(self.indexOf('(')+2, iComma).toReal(),
		self.substring(iComma+2, self.indexOf(')')).toReal()
	);

--------------------------------------------------------------------
-- Collections that are used to filter and categorize model elements
--------------------------------------------------------------------
helper def : Instances : Sequence(UML2!InstanceSpecification) = Sequence {};
helper def : Connectors : Set(UML2!InstanceSpecification) = Set {};
helper def : Comments : Set (UML2!Comment) = Set {};
helper def : Ports : Set (UML2!Port) = Set {};
helper def : States : Set(UML2!State) = Set{};
helper def : Transitions : Set(UML2!Tansition) = Set{};

helper context UML!InstanceSpecification def: getBaseItem() : UML!Classifier = self.classifier->first();

--Find the SimpleStochasticBehavior element associated with a Classifier or an InstanceSpecification
--if it exists. Returns OclUndefined otherwise
helper context UML!Classifier def: getSimpleStochasticBehavior() : CHESS!SimpleStochasticBehavior =
	CHESS!SimpleStochasticBehavior->allInstances()->select(ssb | ssb.base_Class = self)->first();

helper context UML!InstanceSpecification def: getSimpleStochasticBehavior() : CHESS!SimpleStochasticBehavior =
	let instssb : CHESS!SimpleStochasticBehavior = 
		CHESS!SimpleStochasticBehavior->allInstances()->select(ssb | ssb.base_InstanceSpecification = self)->first() in
	if instssb <> OclUndefined then instssb else 
		let base : UML!Class = self.getBaseItem() in 
			if base = OclUndefined then base else base.getSimpleStochasticBehavior() endif
	endif;

--------------------------------------------------------------------
-- Helpers to get dependability information from stereotypes
--------------------------------------------------------------------
	
--Do we have dependability information for this instance?
helper context UML!InstanceSpecification def: hasSBAInformation() : Boolean = self.getSBAStereotype() <> OclUndefined;

--If the InstanceSpecification has its own stereotype then return it,
-- otherwise return the one of the classifier
helper context UML!InstanceSpecification def: getSBAStereotype() : OclAny = 
	let s : OclAny = self.getSBAStereotypeInstance() in
	if s = OclUndefined then self.classifier->first().getSBAStereotypeClassifier() else s endif;

--Get the SBA stereotype applied to the instance, if any
helper context UML!InstanceSpecification def: getSBAStereotypeInstance() : OclAny =
	thisModule.sbaStereotypes->collect(s | s.allInstances())->flatten()->select(st | st.base_InstanceSpecification = self)->first();

--Find the CHESS stereotype that is used on a given instance specification, or on its classifier
helper context UML!Class def: getSBAStereotypeClassifier() : OclAny =
	thisModule.sbaStereotypes->collect(s | s.allInstances())->flatten()->select(st | st.base_Class = self)->first();

--Recursive helper to identify which instances need to be taken into account,
--i.e., to identify those that have dependability information attached, or no
--subinstances
helper context UML!InstanceSpecification  def: findSBAConstituents() : Set(UML!InstanceSpecification) =
	if self.hasSBAInformation() or self.getSubInstances().isEmpty() then
		Set{self}
	else
		self.getSubInstances()->collect(i | i.findSBAConstituents())->flatten()
	endif;

--Get the stereotype associated to an error model transition
helper context UML!Transition def: getSBAStereotype() : OclAny =
	thisModule.sbaTransitions->collect(s | s.allInstances())->
								flatten()->select(t | t.base_Transition = self)->
								first();

--Does this error model transition has dependability information associated with it?
helper context UML!Transition def: hasSBAInformation() : Boolean = not self.getSBAStereotype().oclIsUndefined();

--------------------------------------------------------------------
-- Helpers to get, start from a given InstanceSpecification,
-- port instances and subcomponent instances
--------------------------------------------------------------------
helper context UML!InstanceSpecification def: getPortSlots() : Set(UML!Slot) = 
	self.slot->select(s | s.definingFeature.oclIsKindOf(UML!Port));

helper context UML!InstanceSpecification def: getSubInstanceSlots() : Set(UML!Slot) =
	self.slot->select(s | not s.definingFeature.oclIsKindOf(UML!Port));

helper context UML!InstanceSpecification def: getSubInstances() : Set(UML!InstanceSpecification) = 
	self.getSubInstanceSlots()->collect(s | s.value->first().instance);

helper context UML!InstanceSpecification def: isSubInstanceOf(parent : UML!InstanceSpecification) : Boolean =
	parent.getSubInstances()->includes(self);

--Get the name of a port slot, as the name of the originating port
helper context UML!Slot def: name : String = self.definingFeature.name;
 
--helper context UML!Slot def: getConnectedSlotsInput() : Set(UML!Slot) =
--	self;
--helper context UML!Slot def: getConnectedSlotsOutput() : Set(UML!Slot) = 
--	self;
--helper context UML!Slot def: getConnectedSlots() : Set(UML!Slot) =
--	self.getConnectedSlotsInput->union(self.getConnectedSlotsOutput);

--------------------------------------------------------------------
-- Check if a Port (or Slot) has input or output dataflow
--------------------------------------------------------------------
helper context UML!Slot def: hasInputFlow() : Boolean = self.definingFeature.hasInputFlow();
helper context UML!Slot def: hasOutputFlow() : Boolean = self.definingFeature.hasOutputFlow();
helper context UML!Port def: hasInputFlow() : Boolean =
	let clientserverport : MARTE!ClientServerPort = MARTE!ClientServerPort.allInstances()->select(c | c.base_Port = self)->first() in
	let flowport : SYSML!FlowPort = SYSML!FlowPort.allInstances()->select(c | c.base_Port = self)->first() in
	let flowportmarte : MARTE!FlowPort = MARTE!FlowPort.allInstances()->select(c | c.base_Port = self)->first() in
	if clientserverport <> OclUndefined then clientserverport.hasInputFlow() else
		if flowport <> OclUndefined then flowport.hasInputFlow() else
			if flowportmarte <> OclUndefined then flowportmarte.hasInputFlowMarte() else
				false
	endif endif endif;
helper context UML!Port def: hasOutputFlow() : Boolean =
	let clientserverport : MARTE!ClientServerPort = MARTE!ClientServerPort.allInstances()->select(c | c.base_Port = self)->first() in
	let flowport : SYSML!FlowPort = SYSML!FlowPort.allInstances()->select(c | c.base_Port = self)->first() in
	let flowportmarte : MARTE!FlowPort = MARTE!FlowPort.allInstances()->select(c | c.base_Port = self)->first() in
	if clientserverport <> OclUndefined then clientserverport.hasOutputFlow() else
		if flowport <> OclUndefined then flowport.hasOutputFlow() else
			if flowportmarte <> OclUndefined then flowportmarte.hasOutputFlowMarte() else
				false
	endif endif endif;
helper context SYSML!FlowPort def: hasInputFlow() : Boolean = self.direction <> #out;
helper context SYSML!FlowPort def: hasOutputFlow() : Boolean = self.direction = #out or self.direction = #inout;
helper context MARTE!FlowPort def: hasInputFlowMarte() : Boolean = self.direction <> #out;
helper context MARTE!FlowPort def: hasOutputFlowMarte() : Boolean = self.direction = #out or self.direction = #inout;
helper context MARTE!ClientServerPort def: hasInputFlow() : Boolean = self.kind <> #provided;
helper context MARTE!ClientServerPort def: hasOutputFlow() : Boolean = self.kind <> #required;

--------------------------------------------------------------------
-- Helpers to explore the model and get the component that is
-- connected to the other side of a port
--------------------------------------------------------------------

--Get connectors that are linked to a certain port instance
helper context UML!Slot def: getConnectors() : Set(UML!InstanceSpecification) =
	thisModule.umlInstancesConnectors->
				select(c | not c.slot->select(s | s.definingFeature = self.definingFeature 
					and s.value->first().instance = self.refImmediateComposite())->isEmpty());

--Is the connector instance a "normal" connection
--betweentwo components at the same level?
helper context UML!InstanceSpecification def: isConnection() : Boolean = 
	let sl : OrderedSet(UML!Slot) = self.slot->asOrderedSet() in
	let i1 : UML!InstanceSpecification = sl->first().value->first().instance in
	let i2 : UML!InstanceSpecification = sl->last().value->first().instance in
	if i1.oclIsUndefined() or i2.oclIsUndefined() then false else
		not i1.isSubInstanceOf(i2) and not i2.isSubInstanceOf(i1)
	endif;

--Is the connector instance a delegation?
helper context UML!InstanceSpecification def: isDelegation() : Boolean = 
	let sl : OrderedSet(UML!Slot) = self.slot->asOrderedSet() in
	let i1 : UML!InstanceSpecification = sl->first().value->first().instance in
	let i2 : UML!InstanceSpecification = sl->last().value->first().instance in
	i1.isSubInstanceOf(i2) or i2.isSubInstanceOf(i1);

--Get port instances that are *directly* connected to a certain port instance
helper context UML!Slot def: getConnectedImmediate() : Set(UML!Slot) =
	let connectorsSlots : Set(UML!Slot) = 
	self.getConnectors()->select(c | c.isConnection())->
							collect(c | c.slot)->
							flatten()->
							select(s | s.definingFeature <> self.definingFeature)
	in
	connectorsSlots->collect(s | s.value->first().instance.slot->
									select(sl | sl.definingFeature = s.definingFeature))->flatten();

--Get port instances that receive/send delegation from/to a certain port instance
helper context UML!Slot def: getDelegationEnds() : Set(UML!Slot) =
	let connectorsSlots : Set(UML!Slot) =
	self.getConnectors()->select(c | c.isDelegation())->
							collect(c | c.slot)->
							flatten()->
							select(s | s.definingFeature <> self.definingFeature)
	in
	connectorsSlots->collect(s | s.value->first().instance.slot->
									select(sl | sl.definingFeature = s.definingFeature))->flatten();

--Get taget(s) of delegation in sub-instances
helper context UML!Slot def: getDelegationEndsDownwards() : Set(UML!Slot) = 
	self.getDelegationEnds()->select(s | s.refImmediateComposite().isSubInstanceOf(self.refImmediateComposite()));

--Get source(s) of delegation in parent instance
helper context UML!Slot def: getDelegationEndsUpwards() : Set(UML!Slot) = 
	self.getDelegationEnds()->select(s | self.refImmediateComposite().isSubInstanceOf(s.refImmediateComposite()));

--Get the target of delegation taking into account SBA stereotypes,
--i.e., get the first slot whose owning instance has SBA information.
--(it can be even the slot under examination itself)
helper context UML!Slot def: getSBADelegationsDownwards() : Set(UML!Slot) =
	let inst : UML!InstanceSpecification = self.refImmediateComposite() in
	let deleg : Set(UML!Slot) = self.getDelegationEndsDownwards() in
	if deleg.isEmpty() or 
		inst.hasSBAInformation() or 
		inst.getSubInstances().isEmpty() 
	then
		Set{self}
	else
		deleg->collect(e | e.getSBADelegationsDownwards())->flatten()
	endif;
helper context UML!Slot def: getSBADelegationsUpwards() : Set(UML!Slot) =
	let inst : UML!InstanceSpecification = self.refImmediateComposite() in
	let deleg : Set(UML!Slot) = self.getDelegationEndsUpwards() in
	if deleg.isEmpty() then
		Set{self}
	else
		deleg->collect(e | e.getSBADelegationsUpwards())->flatten()
	endif;

--Get the target of connection taking into account SBA stereotypes,
--i.e., get the first slot whose owning instance has SBA information.
--(it can be even the slot directly connected to the one under examination)
helper context UML!Slot def: getSBAConnections() : Set(UML!Slot) =
	self.getSBADelegationsUpwards()->
		collect(d | d.getConnectedImmediate())->flatten()->
		collect(sl | sl.getSBADelegationsDownwards())->flatten();	

--------------------------------------------------------------------
-- Parse failure modes for SimpleStochasticBehavior elements
--------------------------------------------------------------------

--Split the specification into different parts, one for each port, and find the
--failure modes for the port name passed as input. Calls parseFailureModes() below
helper context String def: parseFailureModesForPort(port : String) : Set(TupleType(fm: String, p: Real)) =
	let strSeq : Sequence(String) = self.trim()->split(';') in
	let strSelected : String = strSeq->select(s | s.trim().startsWith(port))->first() in
	if strSelected = OclUndefined then
		strSeq->first().parseFailureModes()
	else 
		strSelected.parseFailureModes()
	endif;

--From the specification in string format get the failure modes and proabilities for a single port
helper context String def: parseFailureModes() : Set(TupleType(fm: String, p: Real)) =
	let str : String = 
		if self.indexOf('{') < 0 then
			self.trim()
		else
			self.substring(self.indexOf('{')+2, self.size()).replaceAll('}', ' ').trim()
		endif	
	in
	let default : Set(TupleType(fm: String, p: Real)) = Set{Tuple{fm = 'failure', p = 1.0}} in
	if str.size() = 0 then
		default
	else
		let ret : Set(TupleType(fm: String, p: Real)) = 
		str.split(',')->collect(s | s.split(':'))->
			collect(seq | Tuple{fm = seq->first().trim(), p = seq.last().toReal()})
		in
		if ret->isEmpty() then
			default
		else
			ret
	endif endif;

--------------------------------------------------------------------
-- Helpers to manage the metrics
--------------------------------------------------------------------

--temporary parser to retrieve which dependability measure a SBAnalysis refers to
helper context CHESS!StateBasedAnalysis def: WhichMeasure : String =
	if self.measure.startsWith('Reliability') then 'Reliability'
	else if self.measure.startsWith('Availability') then 'Availability'
	else if self.measure.toUpper().startsWith('PFD') then 'PFD' 
	else 'error'
	endif endif endif;
	
--------------------------------------------------------------------
-- Helpers to manage Faults/Errors expressions
--------------------------------------------------------------------
helper context IM!FaultsExpressionFaultNode def: toString(): String = self.Fault.Name;
helper context IM!FaultsExpressionOrNode def: toString(): String = '(' + self.FaultsExpression1.toString() + ' OR ' + self.FaultsExpression2.toString() + ')';
helper context IM!FaultsExpressionAndNode def: toString() : String = '(' + self.FaultsExpression1.toString() + ' AND ' + self.FaultsExpression2.toString() + ')';
helper context IM!FaultsExpressionNotNode def: toString() : String = '(NOT ' + self.FaultsExpression.toString() + ')';

--Get the list of Fault elements involved in a FaultsExpression
helper context IM!FaultsExpressionNode def: faultsList() : Sequence(IM!Fault) = 
	if self.oclIsTypeOf(IM!FaultsExpressionFaultNode) then
		let fexp : IM!FaultsExpressionFaultNode = self in 
		Sequence{fexp.Fault}
	else if self.oclIsTypeOf(IM!FaultsExpressionNotNode) then
		let fexp : IM!FaultsExpressionNotNode = self in 
		fexp.FaultsExpression.faultsList()
	else if self.oclIsTypeOf(IM!FaultsExpressionAndNode) then
		let fexp : IM!FaultsExpressionAndNode = self in 
		fexp.FaultsExpression1.faultsList()->union(fexp.FaultsExpression2.faultsList())
	else if self.oclIsTypeOf(IM!FaultsExpressionOrNode) then
		let fexp : IM!FaultsExpressionOrNode = self in 
		fexp.FaultsExpression1.faultsList()->union(fexp.FaultsExpression2.faultsList())
	else
		Sequence{}	--it should never happen
	endif endif endif endif;

helper context IM!ErrorsExpressionErrorNode def: toString(): String = self.Error.Name;
helper context IM!ErrorsExpressionOrNode def: toString(): String = '(' + self.ErrorsExpression1.toString() + ' OR ' + self.ErrorsExpression2.toString() + ')';

--------------------------------------------------------------------
-- For debugging purposes: pretty print SBA stereotypes
--------------------------------------------------------------------
helper context CHESS!SimpleStochasticBehavior def: toString() : String = 
	'<<SimpleStochasticBehavior>>(' + self.failureOccurrence + ', ' + self.repairDelay + ', ' + self.failureModesDistribution + ')';
helper context CHESS!FLABehavior def: toString() : String = '<<FLABehavior>>(' + self.fptc + ')';
helper context CHESS!ErrorModelBehavior def: toString() : String = '<<ErrorModelBehavior>>(' + self.errorModel + ')';
helper context CHESS!ErrorModel def: toString() : String = '<<ErrorModel>>(' + self.base_StateMachine + ')';
