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); } } } } }
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, }); }
/// <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)); } } } } }