//////////////////////////////////////////// //////////////////////////////////////////// public override Expression substitute(ExpressionSubstitution s) { string ss = makeSubstitutionString(s); if (substitutionCache.ContainsKey(ss)) { return(substitutionCache[ss]); } bool needSubstitution = false; foreach (var fv in freeVariables) { if (s.lookup(fv.name) != null) { needSubstitution = true; } } foreach (var ftv in freeTypeVariables) { if (s.typeSubstitution.map(ftv) != null) { needSubstitution = true; } } Expression result = this; if (needSubstitution) { ExpressionList sArgs = arguments.substitute(s); if (function.name == "==<>") { Debug.Assert(sArgs.count == 2); if (sArgs[0].type.ToStringN() == sArgs[1].type.ToStringN()) { result = new BasicFAE( BFunctionTemplate.eq.getInstance(TypeTuple.make(new[] { sArgs[0].type })), sArgs); } else if (sArgs.freeTypeVariables.Count > 0) { result = new BasicFAE( BFunctionTemplate.eqG.getInstance(TypeTuple.make(from a in sArgs select a.type)), sArgs); } else { result = new BasicLiteralExpression(BooleanValue.makeBooleanValue(false)); } //equality of different types } else { result = new BasicFAE(function.substitute(s.typeSubstitution), sArgs); } } substitutionCache[ss] = result; return(result); }
/////////////////////////////////////////////////////////// public override Expression substitute(ExpressionSubstitution s) { bool needSubstitution = false; foreach (var fv in freeVariables) { if (s.lookup(fv.name) != null) { needSubstitution = true; } } foreach (var ftv in freeTypeVariables) { if (s.typeSubstitution.map(ftv) != null) { needSubstitution = true; } } if (needSubstitution) { return(new BasicQuantifiedTypeExpression(this, s)); } else { return(this); } }
//////////////////////////////////////////// private string makeSubstitutionString(ExpressionSubstitution s) { string result = "["; foreach (var v in freeVariables) { if (s.lookup(v.name) != null) { result += "(" + s.lookup(v.name) + ")"; } else { result += "(" + v.name + ")"; } } result += "] <"; foreach (var tv in freeTypeVariables) { if (s.typeSubstitution.map(tv) != null) { result += "(" + s.typeSubstitution.map(tv).ToString() + ")"; } else { result += "(" + tv.name + ")"; } } return(result); }
public override Expression visit(FAE f) { Debug.Assert(procedure != null); // if (f.ToString().Contains(@"read($h,read($h,$o,AVLTree.root),alloc)")) // Debugger.Break(); Expression result = base.visit(f); var rfae = result as FAE; FunctionTemplate template = procedure.findFunctionTemplate(rfae.function.name); if (rfae != null && template != null && template.body != null && template.attributes.Contains(":inline true")) { var fti = rfae.function as BasicFunctionTemplateInstance; Debug.Assert(fti != null); Debug.Assert(fti.template == template); var substitution = new ExpressionSubstitution(); for (int i = 0; i < template.typeParameters.Length; i++) { substitution.typeSubstitution.add(template.typeParameters[i], fti.typeArguments[i]); } for (int i = 0; i < rfae.arguments.count; i++) { substitution.add(template.body.arguments[i].name, rfae.arguments[i]); } result = template.body.expression.substitute(substitution); // var r1 = result; result = result.visit(this); // if (!ReferenceEquals(r1, result) && r1.ToString().Contains(@"$inv")) // Debugger.Break(); } return(result); }
//////////////////////////////////////////// public override Expression substitute(ExpressionSubstitution s) { Expression result = s.lookup(name); if (result == null) { result = this; } return(result); }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private Expression makeInstance(Expression e, List <IType> tti) { Debug.Assert(tti.Count == e.freeTypeVariables.Count); TypeVariable[] ftvs = e.freeTypeVariables.ToArray(); var s = new ExpressionSubstitution(); for (int i = 0; i < tti.Count; i++) { s.typeSubstitution.add(ftvs[i], tti[i]); } return(e.substitute(s)); }
////////////////////////////////////////////// /////////////////////////////////////////////////////////// public BasicQuantifiedTypeExpression( QuantifiedTypeExpression other, ExpressionSubstitution s ) { quantifier = other.quantifier; variable = new BasicTypeVariable(getFreshTypeVariableName()); s.typeSubstitution.add(other.variable, new VariableType(variable)); expression = other.expression.substitute(s); triggers = new ExpressionList(other.triggers); attributes = other.attributes; s.typeSubstitution.remove(other.variable); }
/////////////////////////////////////////////////////////// public BasicQuantifiedExpression( QuantifiedExpression other, ExpressionSubstitution s ) { scope = other.scope; quantifier = other.quantifier; variable = scope.makeFreshBoundVariable(other.variable.name, other.variable.type.substitute(s.typeSubstitution)); s.add(other.variable.name, new BasicBoundVariableExpression(variable)); expression = other.expression.substitute(s); triggers = (from trs in other.triggers select trs.substitute(s)).ToArray(); if (other.attributes != null) { attributes = (string)(other.attributes.Clone()); } s.remove(other.variable.name); }
//////////////////////////////////////////// public override Expression substitute(ExpressionSubstitution s) { return(new BasicLiteralExpression(this)); }
/////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// internal ExpressionList substitute(ExpressionSubstitution s) { return(new ExpressionList(from e in expressions select e.substitute(s))); }
////////////////////////////////////////////// //////////////////////////////////////////// public override Expression substitute(ExpressionSubstitution s) { return(new BasicProgramVariableExpression(this)); }