/// <summary> /// Here we actually add constraints to our state. /// </summary> private Domain ConstrainLessThan(Expression var, Expression bound, Domain domain) { // First, skip unary coercions on var and bound SkipConversionDecoder skipper = new SkipConversionDecoder(); var = this.context.Decode <Unit, Expression, SkipConversionDecoder>(var, skipper, Unit.Value); bound = this.context.Decode <Unit, Expression, SkipConversionDecoder>(bound, skipper, Unit.Value); Variable left = this.context.Unrefine(var); Variable right = this.context.Unrefine(bound); // add the bound to the set of bounds known SetDomain <Variable> currentBounds = (domain.Value.Contains(left)) ? domain.Value[left] : SetDomain <Variable> .TopValue; return(new Domain(domain.Value.Add(left, currentBounds.Add(right)))); }
/// <summary> /// Here's where the actual work is. We get passed a list of pairs (source,targets) representing /// the assignments t = source for each t in targets. /// /// For our domain, we thus add new mappings for all targets by looking up the bounds of the source and map the source bounds to new target bounds. /// </summary> public Domain ParallelAssign(Pair <Label, Label> edge, IFunctionalMap <Variable, FList <Variable> > sourceTargetMap, Domain state) { EnvironmentDomain <Variable, SetDomain <Variable> > originalState = state.Value; EnvironmentDomain <Variable, SetDomain <Variable> > newState = originalState; foreach (Variable source in sourceTargetMap.Keys) { FList <Variable> targets = sourceTargetMap[source]; // 1) for each target in this assignment, assign it the same bounds as source. // 2) since we also have to map the source bounds, we assign it actually the union of all targets of all bounds of the source. SetDomain <Variable> targetBounds = SetDomain <Variable> .TopValue; if (originalState.Contains(source)) { SetDomain <Variable> originalBounds = originalState[source]; foreach (Variable origBound in originalBounds.Elements) { FList <Variable> targetBoundNames = sourceTargetMap[origBound]; while (targetBoundNames != null) { targetBounds = targetBounds.Add(targetBoundNames.Head); targetBoundNames = targetBoundNames.Tail; } } } if (targetBounds.IsTop) { // have no bounds, so havoc all targets while (targets != null) { newState = newState.Remove(targets.Head); targets = targets.Tail; } } else { while (targets != null) { newState = newState.Add(targets.Head, targetBounds); targets = targets.Tail; } } } return(new Domain(newState)); }