001package org.clafer.ast;
002
003import static org.clafer.ast.Asts.*;
004
005/**
006 *
007 * @param <T> the parameter type
008 * @author jimmy
009 */
010public abstract class AstExprRewriter<T> implements AstExprVisitor<T, AstExpr> {
011
012    public AstBoolExpr rewrite(AstBoolExpr expr, T t) {
013        return (AstBoolExpr) expr.accept(this, t);
014    }
015
016    public AstBoolExpr[] rewrite(AstBoolExpr[] exprs, T t) {
017        AstBoolExpr[] rewritten = new AstBoolExpr[exprs.length];
018        for (int i = 0; i < rewritten.length; i++) {
019            rewritten[i] = rewrite(exprs[i], t);
020        }
021        return rewritten;
022    }
023
024    public AstSetExpr rewrite(AstSetExpr expr, T t) {
025        return (AstSetExpr) expr.accept(this, t);
026    }
027
028    public AstSetExpr[] rewrite(AstSetExpr[] exprs, T t) {
029        AstSetExpr[] rewritten = new AstSetExpr[exprs.length];
030        for (int i = 0; i < rewritten.length; i++) {
031            rewritten[i] = rewrite(exprs[i], t);
032        }
033        return rewritten;
034    }
035
036    @Override
037    public AstExpr visit(AstThis ast, T a) {
038        return ast;
039    }
040
041    @Override
042    public AstExpr visit(AstGlobal ast, T a) {
043        return ast;
044    }
045
046    @Override
047    public AstExpr visit(AstConstant ast, T a) {
048        return ast;
049    }
050
051    @Override
052    public AstExpr visit(AstJoin ast, T a) {
053        return join(rewrite(ast.getLeft(), a), ast.getRight());
054    }
055
056    @Override
057    public AstExpr visit(AstJoinParent ast, T a) {
058        return joinParent(rewrite(ast.getChildren(), a));
059    }
060
061    @Override
062    public AstExpr visit(AstJoinRef ast, T a) {
063        return joinRef(rewrite(ast.getDeref(), a));
064    }
065
066    @Override
067    public AstExpr visit(AstNot ast, T a) {
068        return not(rewrite(ast.getExpr(), a));
069    }
070
071    @Override
072    public AstExpr visit(AstMinus ast, T a) {
073        return minus(rewrite(ast.getExpr(), a));
074    }
075
076    @Override
077    public AstExpr visit(AstCard ast, T a) {
078        return card(rewrite(ast.getSet(), a));
079    }
080
081    @Override
082    public AstExpr visit(AstSetTest ast, T a) {
083        return test(rewrite(ast.getLeft(), a), ast.getOp(), rewrite(ast.getRight(), a));
084    }
085
086    @Override
087    public AstExpr visit(AstCompare ast, T a) {
088        return compare(rewrite(ast.getLeft(), a), ast.getOp(), rewrite(ast.getRight(), a));
089    }
090
091    @Override
092    public AstExpr visit(AstArithm ast, T a) {
093        return arithm(ast.getOp(), rewrite(ast.getOperands(), a));
094    }
095
096    @Override
097    public AstExpr visit(AstSum ast, T a) {
098        return sum(rewrite(ast.getSet(), a));
099    }
100
101    @Override
102    public AstExpr visit(AstBoolArithm ast, T a) {
103        return arithm(ast.getOp(), rewrite(ast.getOperands(), a));
104    }
105
106    @Override
107    public AstExpr visit(AstDifference ast, T a) {
108        return diff(rewrite(ast.getLeft(), a), rewrite(ast.getRight(), a));
109    }
110
111    @Override
112    public AstExpr visit(AstIntersection ast, T a) {
113        return inter(rewrite(ast.getLeft(), a), rewrite(ast.getRight(), a));
114    }
115
116    @Override
117    public AstExpr visit(AstUnion ast, T a) {
118        return union(rewrite(ast.getLeft(), a), rewrite(ast.getRight(), a));
119    }
120
121    @Override
122    public AstExpr visit(AstMembership ast, T a) {
123        return membership(rewrite(ast.getMember(), a), ast.getOp(), rewrite(ast.getSet(), a));
124    }
125
126    @Override
127    public AstExpr visit(AstTernary ast, T a) {
128        return ifThenElse(rewrite(ast.getAntecedent(), a), rewrite(ast.getConsequent(), a), rewrite(ast.getAlternative(), a));
129    }
130
131    @Override
132    public AstExpr visit(AstIfThenElse ast, T a) {
133        return ifThenElse(rewrite(ast.getAntecedent(), a), rewrite(ast.getConsequent(), a), rewrite(ast.getAlternative(), a));
134    }
135
136    @Override
137    public AstExpr visit(AstDowncast ast, T a) {
138        return downcast(rewrite(ast.getBase(), a), ast.getTarget());
139    }
140
141    @Override
142    public AstExpr visit(AstUpcast ast, T a) {
143        return upcast(rewrite(ast.getBase(), a), ast.getTarget());
144    }
145
146    @Override
147    public AstExpr visit(AstLocal ast, T a) {
148        return ast;
149    }
150
151    @Override
152    public AstExpr visit(AstQuantify ast, T a) {
153        AstDecl[] decls = new AstDecl[ast.getDecls().length];
154        for (int i = 0; i < decls.length; i++) {
155            AstDecl decl = ast.getDecls()[i];
156            AstLocal[] locals = new AstLocal[decl.getLocals().length];
157            for (int j = 0; j < locals.length; j++) {
158                locals[j] = (AstLocal) rewrite(decl.getLocals()[j], a);
159            }
160            decls[i] = decl(decl.isDisjoint(), locals, rewrite(decl.getBody(), a));
161        }
162        return quantify(ast.getQuantifier(), decls, rewrite(ast.getBody(), a));
163    }
164}