Esempio n. 1
0
        public override IEnumerable <ProofState> Generate(Statement statement, ProofState state)
        {
            List <List <IVariable> > args  = new List <List <IVariable> >();
            List <IVariable>         mdIns = new List <IVariable>();
            List <Expression>        callArguments;
            IVariable lv;

            InitArgs(state, statement, out lv, out callArguments);

            state.IfVerify = true;


            //TODO: implement this properly
            //var members = state.GetLocalValue(callArguments[0] as NameSegment) as IEnumerable<MemberDecl>;
            //evaluate the argument (methods/lemma)
            var members0 = Interpreter.EvalTacnyExpression(state, callArguments[0]).GetEnumerator();

            members0.MoveNext();
            var members = members0.Current as List <MemberDecl>;

            if (members == null)
            {
                yield break;
            }

            foreach (var member in members)
            {
                MemberDecl md;
                mdIns.Clear();
                args.Clear();

                if (member is NameSegment)
                {
                    //TODO:
                    Console.WriteLine("double check this");
                    md = null;
                    // md = state.GetDafnyProgram().  Members.FirstOrDefault(i => i.Key == (member as NameSegment)?.Name).Value;
                }
                else
                {
                    md = member as MemberDecl;
                }

                // take the membed decl parameters
                var method = md as Method;
                if (method != null)
                {
                    mdIns.AddRange(method.Ins);
                }
                else if (md is Microsoft.Dafny.Function)
                {
                    mdIns.AddRange(((Microsoft.Dafny.Function)md).Formals);
                }
                else
                {
                    Contract.Assert(false, "In Explore Atomic call," + callArguments[0] + "is neither a Method or a Function");
                }

                //evaluate the arguemnts for the lemma to be called
                var instArgs = Interpreter.EvalTacnyExpression(state, callArguments[1]);
                foreach (var ovars in instArgs)
                {
                    Contract.Assert(ovars != null, "In Explore Atomic call," + callArguments[1] + "is not variable");

                    List <IVariable> vars = ovars as List <IVariable> ?? new List <IVariable>();
                    //Contract.Assert(vars != null, Util.Error.MkErr(call_arguments[0], 1, typeof(List<IVariable>)));

                    //for the case when no args, just add an empty list
                    if (mdIns.Count == 0)
                    {
                        args.Add(new List <IVariable>());
                    }
                    for (int i = 0; i < mdIns.Count; i++)
                    {
                        var item = mdIns[i];
                        args.Add(new List <IVariable>());
                        foreach (var arg in vars)
                        {
                            // get variable type
                            Type type = state.GetDafnyVarType(arg.Name);
                            if (type != null)
                            {
                                if (type is UserDefinedType && item.Type is UserDefinedType)
                                {
                                    var udt1 = type as UserDefinedType;
                                    var udt2 = item.Type as UserDefinedType;
                                    if (udt1.Name == udt2.Name)
                                    {
                                        args[i].Add(arg);
                                    }
                                }
                                else
                                {
                                    // if variable type and current argument types match, or the type is yet to be inferred
                                    if (item.Type.ToString() == type.ToString() || type is InferredTypeProxy)
                                    {
                                        args[i].Add(arg);
                                    }
                                }
                            }
                            else
                            {
                                args[i].Add(arg);
                            }
                        }

                        /**
                         * if no type correct variables have been added we can safely return
                         * because we won't be able to generate valid calls
                         */
                        if (args[i].Count == 0)
                        {
                            Debug.WriteLine("No type matching variables were found");
                            yield break;
                        }
                    }

                    foreach (var result in PermuteArguments(args, 0, new List <NameSegment>()))
                    {
                        // create new fresh list of items to remove multiple references to the same object
                        List <Expression> newList = result.Cast <Expression>().ToList().Copy();
                        //TODO: need to double check wirh Vito, why can't use copy ?
                        //Util.Copy.CopyExpressionList(result.Cast<Expression>().ToList());
                        ApplySuffix aps = new ApplySuffix(callArguments[0].tok, new NameSegment(callArguments[0].tok, md.Name, null),
                                                          newList);
                        if (lv != null)
                        {
                            var newState = state.Copy();
                            newState.AddTacnyVar(lv, aps);
                            yield return(newState);
                        }
                        else
                        {
                            var        newState = state.Copy();
                            UpdateStmt us       = new UpdateStmt(aps.tok, aps.tok, new List <Expression>(),
                                                                 new List <AssignmentRhs> {
                                new ExprRhs(aps)
                            });
                            //Printer p = new Printer(Console.Out);
                            //p.PrintStatement(us,0);
                            newState.AddStatement(us);
                            yield return(newState);
                        }
                    }
                }
            }
        }
Esempio n. 2
0
 private TypeRefNode ToTypeRefNode(Microsoft.Dafny.Type t, TokenNode token)
 {
     if (t.IsRevealableType && t.AsRevealableType is TypeSynonymDecl ts && ts.tok != null &&
         ts.tok.filename != null)
     {
         Console.WriteLine("Type synonym reference: " + ts.Name);
         return(new TypeRefNode {
             Name = ts.Name,
             Target = ToTokenNode(ts.tok),
             TypeParams = t.TypeArgs.Select(tp => ToTypeRefNode(tp, token)).ToList(),
             Token = token,
         });
     }
     if (t.IsArrayType)
     {
         Console.WriteLine("Array type reference");
         var at  = t.AsArrayType;
         var tps = new List <TypeRefNode>();
         tps.Add(ToTypeRefNode(t.TypeArgs[0], token));
         return(new TypeRefNode {
             Name = "array",
             TypeParams = tps,
             Token = token,
         });
     }
     if (t.AsCollectionType != null)
     {
         Console.WriteLine("Collection type reference");
         var ct = t.AsCollectionType;
         return(new TypeRefNode {
             Name = ct.CollectionTypeName,
             TypeParams = t.TypeArgs.Select(tp => ToTypeRefNode(tp, token)).ToList(),
             Token = token,
         });
     }
     if (t.IsArrowType)
     {
         Console.WriteLine("Function type reference");
         var at = t.AsArrowType;
         return(new TypeRefNode {
             Name = at.Name,
             TypeParams = t.TypeArgs.Select(tp => ToTypeRefNode(tp, token)).ToList(),
             Special = "Function",
             Token = token,
         });
     }
     if (t.IsTypeParameter)
     {
         Console.WriteLine("Type parameter reference");
         var tp = t.AsTypeParameter;
         return(new TypeRefNode {
             Name = tp.Name,
             Target = ToTokenNode(tp.tok),
             TypeParams = new TypeRefNode[0],
             Token = token,
         });
     }
     if (t.IsDatatype)
     {
         Console.WriteLine("Tuple type reference");
         var dt = t.AsDatatype;
         if (dt is TupleTypeDecl tt)
         {
             return(new TypeRefNode {
                 Name = dt.Name,
                 TypeParams = t.TypeArgs.Select(tp => ToTypeRefNode(tp, token)).ToList(),
                 Special = "Tuple",
                 Token = token,
             });
         }
     }
     if (t.IsNonNullRefType)
     {
         var udt = t.AsNonNullRefType;
         Console.WriteLine("Type reference: " + udt.Name);
         return(new TypeRefNode {
             Name = udt.Name,
             Target = ToTokenNode(udt.tok),
             TypeParams = t.TypeArgs.Select(tp => ToTypeRefNode(tp, token)).ToList(),
             Token = token,
         });
     }
     Console.WriteLine("Other type reference: " + t.ToString());
     return(new TypeRefNode {
         Name = t.ToString(),
         TypeParams = new TypeRefNode[0],
         Token = token,
     });
 }
Esempio n. 3
0
        /// <summary>
        /// Generate all combinations from one permutation
        /// </summary>
        /// <param name="st"></param>
        /// <returns></returns>
        private IEnumerable <Solution> Perm(Statement st)
        {
            List <List <IVariable> > args  = new List <List <IVariable> >();
            List <IVariable>         mdIns = new List <IVariable>();
            List <Expression>        callArguments;
            IVariable lv;

            InitArgs(st, out lv, out callArguments);
            Contract.Assert(tcce.OfSize(callArguments, 2), Error.MkErr(st, 0, 2, callArguments.Count));

            foreach (var member in ResolveExpression(callArguments[0]))
            {
                Contract.Assert(member != null, Error.MkErr(callArguments[0], 1, typeof(Method)));
                MemberDecl md;
                if (member is NameSegment)
                {
                    md = StaticContext.program.Members.FirstOrDefault(i => i.Key == (member as NameSegment)?.Name).Value;
                }
                else
                {
                    md = member as MemberDecl;
                }
                Contract.Assert(md != null, Error.MkErr(callArguments[0], 1, typeof(MemberDecl)));

                // take the membed decl parameters
                var method = md as Method;
                if (method != null)
                {
                    mdIns.AddRange(method.Ins);
                }
                else if (md is Function)
                {
                    mdIns.AddRange(((Function)md).Formals);
                }
                else
                {
                    Contract.Assert(false, Error.MkErr(callArguments[0], 1, $"{typeof(Method)} or {typeof(Function)}"));
                }

                foreach (var ovars in ResolveExpression(callArguments[1]))
                {
                    Contract.Assert(ovars != null, Error.MkErr(callArguments[0], 1, typeof(List <IVariable>)));

                    List <IVariable> vars = ovars as List <IVariable> ?? new List <IVariable>();
                    //Contract.Assert(vars != null, Util.Error.MkErr(call_arguments[0], 1, typeof(List<IVariable>)));



                    for (int i = 0; i < mdIns.Count; i++)
                    {
                        var item = mdIns[i];
                        args.Add(new List <IVariable>());
                        foreach (var arg in vars)
                        {
                            // get variable type
                            Type type = StaticContext.GetVariableType(arg.Name);
                            if (type != null)
                            {
                                if (type is UserDefinedType && item.Type is UserDefinedType)
                                {
                                    var udt1 = type as UserDefinedType;
                                    var udt2 = item.Type as UserDefinedType;
                                    if (udt1.Name == udt2.Name)
                                    {
                                        args[i].Add(arg);
                                    }
                                }
                                else
                                {
                                    // if variable type and current argument types match
                                    if (item.Type.ToString() == type.ToString())
                                    {
                                        args[i].Add(arg);
                                    }
                                }
                            }
                            else
                            {
                                args[i].Add(arg);
                            }
                        }

                        /**
                         * if no type correct variables have been added we can safely return
                         * because we won't be able to generate valid calls
                         */
                        if (args[i].Count == 0)
                        {
                            Debug.WriteLine("No type matching variables were found");
                            yield break;
                        }
                    }

                    foreach (var result in PermuteArguments(args, 0, new List <NameSegment>()))
                    {
                        // create new fresh list of items to remove multiple references to the same object
                        List <Expression> newList = Util.Copy.CopyExpressionList(result.Cast <Expression>().ToList());
                        ApplySuffix       aps     = new ApplySuffix(callArguments[0].tok, new NameSegment(callArguments[0].tok, md.Name, null), newList);
                        if (lv != null)
                        {
                            yield return(AddNewLocal(lv, aps));
                        }
                        else
                        {
                            UpdateStmt us = new UpdateStmt(aps.tok, aps.tok, new List <Expression>(), new List <AssignmentRhs> {
                                new ExprRhs(aps)
                            });
                            yield return(AddNewStatement(us, us));
                        }
                    }
                }
            }
        }