public static TypeInstanceCollector collect(Procedure procedure)
        {
            var result = new TypeInstanceCollector(procedure);

            result.collect();
            return(result);
        }
        private void addConditionalMapEqualityAxiom(Expression[] i, Expression mu, Expression m,
                                                    ITypeTuple typeArguments)
        {
            Debug.Assert(mu.type.ToStringN() == m.type.ToStringN());
            string mlIndex = TypeInstanceCollector.makeString(typeArguments);

            Debug.Assert(tic.functionInstanceMap["MapRead"].ContainsKey(mlIndex));
            Debug.Assert(m.type is MapType);
            var mt = m.type as MapType;

            TypeInstanceCollector.GFunctionInstance[] tpis = (from tpi in tic.functionInstanceMap["MapRead"].Values
                                                              where
                                                              tpi.function.typeArguments.First().ToStringN() ==
                                                              mt.ToStringN()
                                                              select tpi).ToArray();
            Debug.Assert(
                (from tpi in tpis select TypeInstanceCollector.makeString(tpi.function.typeArguments)).Contains(
                    TypeInstanceCollector.makeString(typeArguments)));
            foreach (var tpi in tpis)
            {
                var ta = tpi.function.typeArguments;
                Debug.Assert(ta.Count() == mt.typeParameters.Count() + 1);
                Debug.Assert(ta.First().ToStringN() == mt.ToStringN());
                var mta  = ta.Skip(1).ToArray();
                var ts   = new TypeParameterInstantiation(mt.typeParameters, mta);
                var at   = (from a in mt.domain select a.substitute(ts)).ToArray();
                var rt   = mt.range.substitute(ts);
                var bvs  = (from a in at select procedure.makeFreshBoundVariable(a)).ToArray();
                var bves =
                    (from bv in bvs select new BasicBoundVariableExpression(bv)).ToArray();

                if (TypeInstanceCollector.makeString(ta) == TypeInstanceCollector.makeString(typeArguments))
                {
                    addAxiom(
                        sentence(implication(inEquality(bves, i), equality(ml(m, bves, mta, rt), ml(mu, bves, mta, rt)))));
                }
                else
                {
                    addAxiom(sentence(equality(ml(m, bves, mta, rt), ml(mu, bves, mta, rt))));
                }
            }
        }
 public static void remove(Procedure procedure, TypeInstanceCollector tic)
 {
     new MapWriteRemover(procedure, tic).remove();
 }
 public MapWriteRemover(Procedure procedure, TypeInstanceCollector tic)
     : base(procedure)
 {
     this.tic = tic;
 }