public static bool IsResolvable(ExpressionTree expt, ProofState state) { Contract.Requires(expt.IsRoot()); var leafs = expt.GetLeafData(); if (leafs == null) { throw new ArgumentNullException(nameof(leafs)); } foreach (var leaf in leafs) { if (leaf is NameSegment) { var ns = leaf as NameSegment; if (state.ContainTacnyVal(ns)) { var local = state.GetTacnyVarValue(ns); if (local is ApplySuffix || local is IVariable || local is NameSegment || local is Statement) { return(false); } } else { return(false); } } else if (!(leaf is LiteralExpr)) { if (leaf is ApplySuffix) { return(false); } } } return(true); }
public static IEnumerable<ProofState> RegisterVariable(TacticVarDeclStmt declaration, ProofState state) { if(declaration.Update == null) yield break; var rhs = declaration.Update as UpdateStmt; if(rhs == null) { // check if rhs is SuchThatStmt if(declaration.Update is AssignSuchThatStmt) { foreach(var item in declaration.Locals) state.AddTacnyVar(item, null); foreach(var item in EvalSuchThatStmt(declaration.Update as AssignSuchThatStmt, state)) { yield return item.Copy(); } } else { foreach(var item in declaration.Locals) state.AddTacnyVar(item, null); } } else { foreach(var item in rhs.Rhss) { int index = rhs.Rhss.IndexOf(item); Contract.Assert(declaration.Locals.ElementAtOrDefault(index) != null, "register var err"); var exprRhs = item as ExprRhs; if(exprRhs?.Expr is ApplySuffix) { var aps = (ApplySuffix)exprRhs.Expr; foreach(var result in EvalTacnyExpression(state, aps)) { state.AddTacnyVar(declaration.Locals[index], result); } } else if(exprRhs?.Expr is Dafny.LiteralExpr) { state.AddTacnyVar(declaration.Locals[index], (Dafny.LiteralExpr)exprRhs?.Expr); } else if(exprRhs?.Expr is Dafny.NameSegment) { var name = ((Dafny.NameSegment)exprRhs.Expr).Name; if(state.ContainTacnyVal(name)) // in the case that referring to an exisiting tvar, dereference it state.AddTacnyVar(declaration.Locals[index], state.GetTacnyVarValue(name)); } else { state.AddTacnyVar(declaration.Locals[index], exprRhs?.Expr); } } } yield return state.Copy(); }
public static IEnumerable<object> EvalTacnyExpression(ProofState state, Expression expr) { Contract.Requires<ArgumentNullException>(state != null, "state"); Contract.Requires<ArgumentNullException>(expr != null, "expr"); if(expr is NameSegment) { var ns = (NameSegment)expr; if(state.ContainTacnyVal(ns.Name)) { yield return state.GetTacnyVarValue(ns.Name); } else { yield return ns; } } else if(expr is ApplySuffix) { var aps = (ApplySuffix)expr; if(state.IsTacticCall(aps)) { /* var us = new UpdateStmt(aps.tok, aps.tok, new List<Expression>() { aps.Lhs }, new List<AssignmentRhs>() { new ExprRhs(aps) }); foreach(var item in ApplyNestedTactic(state, state.DafnyVars(), us).Select(x => x.GetGeneratedCode())) { yield return item; } */ } else if(aps.Lhs is ExprDotName) { foreach(var item in EvalTacnyExpression(state, aps.Lhs)) { if(item is Expression) { yield return new ApplySuffix(aps.tok, (Expression)item, aps.Args); } else { Contract.Assert(false, "Unexpected ExprNotName case"); } } } else { // get the keyword of this application string sig = Util.GetSignature(aps); // Try to evaluate as tacny expression // using reflection find all classes that extend EAtomic var types = Assembly.GetAssembly(typeof(EAtomic.EAtomic)) .GetTypes() .Where(t => t.IsSubclassOf(typeof(EAtomic.EAtomic))); foreach(var eType in types) { var eatomInst = Activator.CreateInstance(eType) as EAtomic.EAtomic; if(sig == eatomInst?.Signature) { //TODO: validate input countx var enumerable = eatomInst?.Generate(aps, state); if(enumerable != null) foreach(var item in enumerable) { yield return item; yield break; } } } // if we reached this point, rewrite the apply suffix foreach(var item in EvalTacnyExpression(state, aps.Lhs)) { if(!(item is NameSegment)) { //TODO: warning } else { var argList = new List<Expression>(); foreach(var arg in aps.Args) { foreach(var result in EvalTacnyExpression(state, arg)) { if(result is Expression) argList.Add(result as Expression); else argList.Add(Util.VariableToExpression(result as IVariable)); break; } } yield return new ApplySuffix(aps.tok, aps.Lhs, argList); } } } } else if(expr is ExprDotName) { var edn = (ExprDotName)expr; var ns = edn.Lhs as NameSegment; if(ns != null && state.ContainDafnyVar(ns)) { var newLhs = state.GetTacnyVarValue(ns); var lhs = newLhs as Expression; if(lhs != null) yield return new ExprDotName(edn.tok, lhs, edn.SuffixName, edn.OptTypeArguments); } yield return edn; } else if(expr is UnaryOpExpr) { var op = (UnaryOpExpr)expr; foreach(var result in EvalTacnyExpression(state, op.E)) { switch(op.Op) { case UnaryOpExpr.Opcode.Cardinality: if(!(result is IEnumerable)) { var resultExp = result is IVariable ? Util.VariableToExpression(result as IVariable) : result as Expression; yield return new UnaryOpExpr(op.tok, op.Op, resultExp); } else { var enumerator = result as IList; if(enumerator != null) yield return new Dafny.LiteralExpr(op.tok, enumerator.Count); } yield break; case UnaryOpExpr.Opcode.Not: if(result is Dafny.LiteralExpr) { var lit = (Dafny.LiteralExpr)result; if(lit.Value is bool) { // inverse the bool value yield return new Dafny.LiteralExpr(op.tok, !(bool)lit.Value); } else { Contract.Assert(false); //TODO: error message } } else { var resultExp = result is IVariable ? Util.VariableToExpression(result as IVariable) : result as Expression; yield return new UnaryOpExpr(op.tok, op.Op, resultExp); } yield break; default: Contract.Assert(false, "Unsupported Unary Operator"); yield break; } } } else if(expr is DisplayExpression) { var dexpr = (DisplayExpression)expr; if(dexpr.Elements.Count == 0) { yield return dexpr.Copy(); } else { foreach(var item in EvalDisplayExpression(state, dexpr)) { yield return item; } } } else { yield return expr; } }
public static IEnumerable <ProofState> RegisterVariable(TacticVarDeclStmt declaration, ProofState state) { if (declaration.Update == null) { yield break; } var rhs = declaration.Update as UpdateStmt; if (rhs == null) { // check if rhs is SuchThatStmt if (declaration.Update is AssignSuchThatStmt) { foreach (var item in declaration.Locals) { state.AddTacnyVar(item, null); } foreach (var item in EvalSuchThatStmt(declaration.Update as AssignSuchThatStmt, state)) { yield return(item.Copy()); } } else { foreach (var item in declaration.Locals) { state.AddTacnyVar(item, null); } } } else { foreach (var item in rhs.Rhss) { int index = rhs.Rhss.IndexOf(item); Contract.Assert(declaration.Locals.ElementAtOrDefault(index) != null, "register var err"); var exprRhs = item as ExprRhs; if (exprRhs?.Expr is ApplySuffix) { var aps = (ApplySuffix)exprRhs.Expr; foreach (var result in EvalTacnyExpression(state, aps)) { state.AddTacnyVar(declaration.Locals[index], result); } } else if (exprRhs?.Expr is Dafny.LiteralExpr) { state.AddTacnyVar(declaration.Locals[index], (Dafny.LiteralExpr)exprRhs?.Expr); } else if (exprRhs?.Expr is Dafny.NameSegment) { var name = ((Dafny.NameSegment)exprRhs.Expr).Name; if (state.ContainTacnyVal(name)) { // in the case that referring to an exisiting tvar, dereference it state.AddTacnyVar(declaration.Locals[index], state.GetTacnyVarValue(name)); } } else { state.AddTacnyVar(declaration.Locals[index], exprRhs?.Expr); } } } yield return(state.Copy()); }
public static IEnumerable <object> EvalTacnyExpression(ProofState state, Expression expr) { Contract.Requires <ArgumentNullException>(state != null, "state"); Contract.Requires <ArgumentNullException>(expr != null, "expr"); if (expr is NameSegment) { var ns = (NameSegment)expr; if (state.ContainTacnyVal(ns.Name)) { yield return(state.GetTacnyVarValue(ns.Name)); } else { yield return(ns); } } else if (expr is ApplySuffix) { var aps = (ApplySuffix)expr; if (state.IsTacticCall(aps)) { /* * var us = new UpdateStmt(aps.tok, aps.tok, new List<Expression>() { aps.Lhs }, * new List<AssignmentRhs>() { new ExprRhs(aps) }); * foreach(var item in ApplyNestedTactic(state, state.DafnyVars(), us).Select(x => x.GetGeneratedCode())) { * yield return item; * } */ } else if (aps.Lhs is ExprDotName) { foreach (var item in EvalTacnyExpression(state, aps.Lhs)) { if (item is Expression) { yield return(new ApplySuffix(aps.tok, (Expression)item, aps.Args)); } else { Contract.Assert(false, "Unexpected ExprNotName case"); } } } else { // get the keyword of this application string sig = Util.GetSignature(aps); // Try to evaluate as tacny expression // using reflection find all classes that extend EAtomic var types = Assembly.GetAssembly(typeof(EAtomic.EAtomic)) .GetTypes() .Where(t => t.IsSubclassOf(typeof(EAtomic.EAtomic))); foreach (var eType in types) { var eatomInst = Activator.CreateInstance(eType) as EAtomic.EAtomic; if (sig == eatomInst?.Signature) { //TODO: validate input countx var enumerable = eatomInst?.Generate(aps, state); if (enumerable != null) { foreach (var item in enumerable) { yield return(item); yield break; } } } } // if we reached this point, rewrite the apply suffix foreach (var item in EvalTacnyExpression(state, aps.Lhs)) { if (!(item is NameSegment)) { //TODO: warning } else { var argList = new List <Expression>(); foreach (var arg in aps.Args) { foreach (var result in EvalTacnyExpression(state, arg)) { if (result is Expression) { argList.Add(result as Expression); } else { argList.Add(Util.VariableToExpression(result as IVariable)); } break; } } yield return(new ApplySuffix(aps.tok, aps.Lhs, argList)); } } } } else if (expr is ExprDotName) { var edn = (ExprDotName)expr; var ns = edn.Lhs as NameSegment; if (ns != null && state.ContainDafnyVar(ns)) { var newLhs = state.GetTacnyVarValue(ns); var lhs = newLhs as Expression; if (lhs != null) { yield return(new ExprDotName(edn.tok, lhs, edn.SuffixName, edn.OptTypeArguments)); } } yield return(edn); } else if (expr is UnaryOpExpr) { var op = (UnaryOpExpr)expr; foreach (var result in EvalTacnyExpression(state, op.E)) { switch (op.Op) { case UnaryOpExpr.Opcode.Cardinality: if (!(result is IEnumerable)) { var resultExp = result is IVariable ? Util.VariableToExpression(result as IVariable) : result as Expression; yield return(new UnaryOpExpr(op.tok, op.Op, resultExp)); } else { var enumerator = result as IList; if (enumerator != null) { yield return(new Dafny.LiteralExpr(op.tok, enumerator.Count)); } } yield break; case UnaryOpExpr.Opcode.Not: if (result is Dafny.LiteralExpr) { var lit = (Dafny.LiteralExpr)result; if (lit.Value is bool) { // inverse the bool value yield return(new Dafny.LiteralExpr(op.tok, !(bool)lit.Value)); } else { Contract.Assert(false); //TODO: error message } } else { var resultExp = result is IVariable?Util.VariableToExpression(result as IVariable) : result as Expression; yield return(new UnaryOpExpr(op.tok, op.Op, resultExp)); } yield break; default: Contract.Assert(false, "Unsupported Unary Operator"); yield break; } } } else if (expr is DisplayExpression) { var dexpr = (DisplayExpression)expr; if (dexpr.Elements.Count == 0) { yield return(dexpr.Copy()); } else { foreach (var item in EvalDisplayExpression(state, dexpr)) { yield return(item); } } } else { yield return(expr); } }
public static bool IsResolvable(ExpressionTree expt, ProofState state) { Contract.Requires(expt.IsRoot()); var leafs = expt.GetLeafData(); if (leafs == null) throw new ArgumentNullException(nameof(leafs)); foreach (var leaf in leafs) { if (leaf is NameSegment) { var ns = leaf as NameSegment; if (state.ContainTacnyVal(ns)) { var local = state.GetTacnyVarValue(ns); if (local is ApplySuffix || local is IVariable || local is NameSegment || local is Statement) return false; } else { return false; } } else if (!(leaf is LiteralExpr)) { if (leaf is ApplySuffix) { return false; } } } return true; }