private void TransformImpls(HashSet <Procedure> yieldingProcs, Dictionary <Implementation, List <Cmd> > implToPreconditions)
 {
     foreach (var impl in absyMap.Keys.OfType <Implementation>())
     {
         // Add disjointness assumptions at loop headers and after each parallel call
         // for each duplicate implementation of yielding procedures.
         // Disjointness assumptions after yields are added inside TransformImpl which is called for
         // all implementations except for a mover procedure at its disappearing layer.
         // But this is fine because a mover procedure at its disappearing layer does not have a yield in it.
         linearPermissionInstrumentation.AddDisjointnessAssumptions(impl, yieldingProcs);
         var yieldingProc = GetYieldingProc(impl);
         if (yieldingProc is MoverProc && yieldingProc.upperLayer == layerNum)
         {
             continue;
         }
         TransformImpl(impl, implToPreconditions[impl]);
     }
 }
        public static List <Declaration> TransformImplementations(
            CivlTypeChecker civlTypeChecker,
            LinearTypeChecker linearTypeChecker,
            int layerNum,
            Dictionary <Absy, Absy> absyMap,
            HashSet <Procedure> yieldingProcs)
        {
            var linearHelper = new LinearPermissionInstrumentation(civlTypeChecker, linearTypeChecker, layerNum, absyMap);
            var yieldingProcInstrumentation = new YieldingProcInstrumentation(
                civlTypeChecker,
                linearTypeChecker,
                linearHelper,
                layerNum,
                absyMap,
                yieldingProcs);

            foreach (var impl in absyMap.Keys.OfType <Implementation>())
            {
                // Add disjointness assumptions at beginning, loop headers, and after each call or parallel call.
                // These are added for each duplicate implementation of yielding procedures.
                // Disjointness assumptions after yields are added inside TransformImpl which is called for
                // all implementations except for a mover procedure at its disappearing layer.
                // But this is fine because a mover procedure at its disappearing layer does not have a yield in it.
                linearHelper.AddDisjointnessAssumptions(impl, yieldingProcs);
                var originalImpl = absyMap[impl] as Implementation;
                var proc         = civlTypeChecker.procToYieldingProc[originalImpl.Proc];
                if (!(proc is MoverProc && proc.upperLayer == layerNum))
                {
                    yieldingProcInstrumentation.TransformImpl(originalImpl, impl);
                }
            }

            List <Declaration> decls = new List <Declaration>(yieldingProcInstrumentation.noninterferenceCheckerDecls);

            foreach (Procedure proc in yieldingProcInstrumentation.parallelCallPreconditionCheckers.Values)
            {
                decls.Add(proc);
            }
            decls.Add(yieldingProcInstrumentation.wrapperNoninterferenceCheckerProc);
            decls.Add(yieldingProcInstrumentation.WrapperNoninterferenceCheckerImpl());
            return(decls);
        }