1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using Microsoft.Boogie.VCExprAST;
namespace Microsoft.Boogie.TPTP
{
// Visitor for collecting the occurring function symbols in a VCExpr,
// and for creating the corresponding declarations
public class TypeDeclCollector : BoundVarTraversingVCExprVisitor<bool, bool> {
private readonly HashSet<string/*!*/>/*!*/ KnownStoreFunctions = new HashSet<string>();
private readonly HashSet<string/*!*/>/*!*/ KnownSelectFunctions = new HashSet<string>();
private readonly UniqueNamer Namer;
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(Namer != null);
Contract.Invariant(AllDecls != null);
Contract.Invariant(IncDecls != null);
Contract.Invariant(cce.NonNull(KnownFunctions));
Contract.Invariant(cce.NonNull(KnownVariables));
}
public TypeDeclCollector(UniqueNamer namer) {
Contract.Requires(namer != null);
this.Namer = namer;
}
// not used
protected override bool StandardResult(VCExpr node, bool arg) {
//Contract.Requires(node != null);
return true;
}
private readonly List<string/*!>!*/> AllDecls = new List<string/*!*/> ();
private readonly List<string/*!>!*/> IncDecls = new List<string/*!*/> ();
private readonly HashSet<Function/*!*/>/*!*/ KnownFunctions = new HashSet<Function/*!*/>();
private readonly HashSet<VCExprVar/*!*/>/*!*/ KnownVariables = new HashSet<VCExprVar/*!*/>();
public List<string/*!>!*/> AllDeclarations { get {
Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() ));
List<string>/*!>!*/ res = new List<string/*!*/> ();
res.AddRange(AllDecls);
return res;
} }
public List<string/*!>!*/> GetNewDeclarations() {
Contract.Ensures(cce.NonNullElements(Contract.Result<List<string>>() ));
List<string>/*!>!*/ res = new List<string/*!*/>();
res.AddRange(IncDecls);
IncDecls.Clear();
return res;
}
private void AddDeclaration(string decl) {
Contract.Requires(decl != null);
AllDecls.Add(decl);
IncDecls.Add(decl);
}
public void Collect(VCExpr expr) {
Contract.Requires(expr != null);
Traverse(expr, true);
}
///////////////////////////////////////////////////////////////////////////
public override bool Visit(VCExprNAry node, bool arg) {
Contract.Requires(node != null);
if (node.Op is VCExprStoreOp) {
string name = TPTPExprLineariser.Lowercase(SimplifyLikeExprLineariser.StoreOpName(node));
if (!KnownStoreFunctions.Contains(name)) {
var id = KnownStoreFunctions.Count;
if (CommandLineOptions.Clo.MonomorphicArrays) {
var sel = TPTPExprLineariser.Lowercase(SimplifyLikeExprLineariser.SelectOpName(node));
var eq = "=";
if (node[node.Arity - 1].Type.IsBool)
eq = "<=>";
string xS = "", yS = "";
string dist = "";
for (int i = 0; i < node.Arity - 2; i++) {
if (i != 0) {
dist += " | ";
xS += ",";
yS += ",";
}
var x = "X" + i;
var y = "Y" + i;
xS += x;
yS += y;
dist += string.Format("({0} != {1})", x, y);
}
string ax1 = "fof(selectEq" + id + ", axiom, ! [M,V," + xS + "] : (" +
string.Format("{0}({1}(M,{2},V),{2}) {3} V", sel, name, xS, eq) + ")).";
string ax2 = "fof(selectNeq" + id + ", axiom, ! [M,V," + xS + "," + yS + "] : (" +
string.Format("( {0} ) => ", dist) +
string.Format("{0}({1}(M,{2},V),{3}) {4} {0}(M,{3})", sel, name, xS, yS, eq) + ")).";
AddDeclaration(ax1);
AddDeclaration(ax2);
}
KnownStoreFunctions.Add(name);
}
//
}
return base.Visit(node, arg);
}
public override bool Visit(VCExprVar node, bool arg) {
return base.Visit(node, arg);
}
}
}
|