public AbstractImageSpec WitnessCompose_TopParam(GrammarRule rule, AbstractImageSpec spec) { Program.DEBUG("Entered WitnessCompose_TopParam"); var result = new Dictionary <State, object>(); foreach (var example in spec.AbstractImageExamples) { State inputState = example.Key; var output = example.Value as AbstractImage; // None values are meaningless, so we don't consider them if (output.ContainsNoneValue()) { Program.DEBUG("Returning null from WitnessCompose_TopParam --> output contained NONE value"); return(null); } AbstractImage preimage = new AbstractImage(output.x, output.y, output.w, output.h); for (int ay = preimage.y; ay < preimage.y + preimage.h; ay++) { for (int ax = preimage.x; ax < preimage.x + preimage.w; ax++) { AbstractValue output_ab_val = output.GetAbstractValueAtPixel(ax, ay); preimage.SetAbstractValueAtPixel(ax, ay, output_ab_val.Clone().UnionWith(new AbstractValue(AbstractConstants.ZERO))); } } result[inputState] = preimage; } return(new AbstractImageSpec(result)); }
public AbstractImageSpec WitnessCompose_BottomParam(GrammarRule rule, AbstractImageSpec spec, AbstractImageSpec topSpec) { Program.DEBUG("Entered WitnessCompose_BottomParam"); var result = new Dictionary <State, object>(); foreach (var example in spec.AbstractImageExamples) { State inputState = example.Key; var output = example.Value as AbstractImage; if (output.ContainsNoneValue()) { Program.DEBUG("null from WitnessCompose_BottomParam --> output contained NONE value"); return(null); } AbstractImage top_image = (AbstractImage)topSpec.AbstractImageExamples[inputState]; // If either the top_image or output contain a pixel with "NONE" as output, then // it's an invalid candidate image if (top_image.ContainsNoneValue()) { Program.DEBUG("null from WitnessCompose_BottomParam --> top contained NONE value"); return(null); } // TODO: Handle different dimensions for bottom_preimage, currently we assume output is proper dimension // Future Idea: use NONE values or some sort of NEGATIVE value to indicate "out of bounds, but still a // viable candidate if a top image overwhelmed me. Could make all images arbitrarily sized, like 100x100 or something // to enable composition AbstractImage bottom_preimage = new AbstractImage(output.x, output.y, output.w, output.h); for (int ay = bottom_preimage.y; ay < bottom_preimage.y + bottom_preimage.h; ay++) { for (int ax = bottom_preimage.x; ax < bottom_preimage.x + bottom_preimage.w; ax++) { AbstractValue output_ab_val = output.GetAbstractValueAtPixel(ax, ay); if (top_image.InBounds(ax, ay)) // Checking that the x and y coords are in the bounds for top_image { AbstractValue top_image_ab_val = top_image.GetAbstractValueAtPixel(ax, ay); // ONLY could allow 0 on output (thus top and bottom must both be 0) if (output_ab_val.Equals(AbstractConstants.ZERO)) { // If the top image isn't ONLY 0, then it's impossible to produce an output that is ONLY 0 if (!top_image_ab_val.Equals(AbstractConstants.ZERO)) { Program.DEBUG("null from WitnessCompose_BottomParam --> top image didn't allow 0"); return(null); } // Top image IS only 0, so the only value must be 0 for the bottom preimage else { bottom_preimage.SetAbstractValueAtPixel(ax, ay, new AbstractValue(AbstractConstants.ZERO)); } } // Output is ONLY nonzeros else if (!output_ab_val.AllowsColor(0)) { // If the top_image doesn't allow 0, that's cool. // It means that our bottom_preimage can contain literally anything // since its contents will be completely ignored if (!top_image_ab_val.AllowsColor(0)) { // But, the abstract domains must be equivalent between output and top in this case if (top_image_ab_val.Equals(output_ab_val)) { bottom_preimage.SetAbstractValueAtPixel(ax, ay, new AbstractValue(AbstractConstants.ANY)); } // Otherwise, no bottom preimage could be generated to satisfy this else { Program.DEBUG("null from WitnessCompose_BottomParam --> top != output"); return(null); } } // otherwise, if top image does allow 0, our bottom preimage // takes on the the nonzero values in output // Example: // output: [1,2,3] // top: [0,1,2,3] // bottom: [1,2,3] else { AbstractValue nonzero_top_image_ab_vals = AbstractValue.Intersect( new AbstractValue(AbstractConstants.NONZERO), top_image_ab_val ); // First, sanity check! Ensure the nonzero elements of top // are contained within output, otherwise that's bad and we return null if (!output_ab_val.ContainsAllColors(nonzero_top_image_ab_vals)) { Program.DEBUG("null from WitnessCompose_BottomParam --> output val wasn't superset of nonzero top vals"); return(null); } // Now, easy-peasy, just set bottom_preimage to output bottom_preimage.SetAbstractValueAtPixel(ax, ay, output_ab_val.Clone()); } } // output contains nonzero AND allows 0 else if (output_ab_val.AllowsColor(0) && output_ab_val.HammingWeight() > 1) { // If the top_image doesn't allow 0, that's bad! // means we can't get 0 on output, so return null if (!top_image_ab_val.AllowsColor(0)) { Program.DEBUG("null from WitnessCompose_BottomParam --> top image didn't allow 0, which is impossible given output accepts zero (and some other nonzeros)"); return(null); } // otherwise, if top image does allow 0, our bottom preimage is the values on output // Example: // output: [0,1,2,3] // top: [0,1] // bottom: [0,1,2,3] else { // First, sanity check! Ensure the elements of top // are contained within elementss of output, invalid if (!output_ab_val.ContainsAllColors(top_image_ab_val)) { Program.DEBUG("null from WitnessCompose_BottomParam --> nonzero output val wasn't superset of nonzero top vals"); return(null); } // Now, set to the values of output bottom_preimage.SetAbstractValueAtPixel(ax, ay, output_ab_val.Clone()); } } else { throw new Exception("We should not have thrown this. Check WitnessCompose_BottomParam."); } } else { bottom_preimage.SetAbstractValueAtPixel(ax, ay, output_ab_val.Clone()); // clone out of fear and respect } } } result[inputState] = bottom_preimage; } return(new AbstractImageSpec(result)); }