001package org.clafer.ast; 002 003import org.clafer.ast.AstQuantify.Quantifier; 004 005/** 006 * Import this class to access all AST building functions. 007 * <pre> 008 * import static org.clafer.ast.Asts.*; 009 * </pre> 010 * 011 * @author jimmy 012 */ 013public class Asts { 014 015 private Asts() { 016 } 017 public static final AstIntClafer IntType = AstIntClafer.Singleton; 018 public static final AstBoolClafer BoolType = AstBoolClafer.Singleton; 019 // Cardinality keywords 020 public static final Card Any = new Card(); 021 public static final Card Optional = new Card(0, 1); 022 public static final Card Mandatory = new Card(1, 1); 023 public static final Card Many = new Card(1); 024 // Not going to define group cardinality key words since they are confusing 025 // and they don't work like they do in the Clafer compiler. For example: 026 // opt A 027 // B 028 // C 029 // is desugarred in the Clafer compiler to 030 // opt A 031 // B ? 032 // C ? 033 // So the keywords implicitly affect the cardinalities of the children. If 034 // these keywords were defined in the API as below, they do not desugar the 035 // children and the behaviour is unexpected. Hence leave them undefined. 036 // public static final Card Opt = new Card(); 037 // public static final Card Mux = new Card(0, 1); 038 // public static final Card Xor = new Card(1, 1); 039 // public static final Card Or = new Card(1); 040 041 public static AstModel newModel() { 042 return new AstModel(); 043 } 044 045 public static AstThis $this() { 046 return new AstThis(); 047 } 048 049 public static AstGlobal global(AstClafer type) { 050 return new AstGlobal(type); 051 } 052 053 public static AstConstant constant(int value) { 054 return constant(IntType, value); 055 } 056 057 public static AstConstant constant(AstClafer type, int... value) { 058 return new AstConstant(type, value); 059 } 060 061 public static AstSetExpr join(AstSetExpr left, AstConcreteClafer right) { 062 return new AstJoin(left, right); 063 } 064 065 public static AstSetExpr joinParent(AstSetExpr children) { 066 return new AstJoinParent(children); 067 } 068 069 public static AstSetExpr joinRef(AstSetExpr deref) { 070 return new AstJoinRef(deref); 071 } 072 073 public static AstBoolExpr not(AstBoolExpr expr) { 074 return new AstNot(expr); 075 } 076 077 public static AstSetExpr minus(AstSetExpr expr) { 078 return new AstMinus(expr); 079 } 080 081 public static AstSetExpr card(AstSetExpr set) { 082 return new AstCard(set); 083 } 084 085 public static AstBoolExpr test(AstSetExpr left, AstSetTest.Op op, AstSetExpr right) { 086 return new AstSetTest(left, op, right); 087 } 088 089 public static AstBoolExpr equal(AstSetExpr left, AstSetExpr right) { 090 return test(left, AstSetTest.Op.Equal, right); 091 } 092 093 public static AstBoolExpr notEqual(AstSetExpr left, AstSetExpr right) { 094 return test(left, AstSetTest.Op.NotEqual, right); 095 } 096 097 public static AstBoolExpr compare(AstSetExpr left, AstCompare.Op op, AstSetExpr right) { 098 return new AstCompare(left, op, right); 099 } 100 101 public static AstBoolExpr lessThan(AstSetExpr left, AstSetExpr right) { 102 return compare(left, AstCompare.Op.LessThan, right); 103 } 104 105 public static AstBoolExpr lessThanEqual(AstSetExpr left, AstSetExpr right) { 106 return compare(left, AstCompare.Op.LessThanEqual, right); 107 } 108 109 public static AstBoolExpr greaterThan(AstSetExpr left, AstSetExpr right) { 110 return compare(left, AstCompare.Op.GreaterThan, right); 111 } 112 113 public static AstBoolExpr greaterThanEqual(AstSetExpr left, AstSetExpr right) { 114 return compare(left, AstCompare.Op.GreaterThanEqual, right); 115 } 116 117 public static AstSetExpr arithm(AstArithm.Op op, AstSetExpr... operands) { 118 if (operands.length == 1) { 119 return operands[0]; 120 } 121 return new AstArithm(op, operands); 122 } 123 124 public static AstSetExpr add(AstSetExpr... addends) { 125 return arithm(AstArithm.Op.Add, addends); 126 } 127 128 public static AstSetExpr sub(AstSetExpr... subtrahends) { 129 return arithm(AstArithm.Op.Sub, subtrahends); 130 } 131 132 public static AstSetExpr mul(AstSetExpr... multipliers) { 133 return arithm(AstArithm.Op.Mul, multipliers); 134 } 135 136 public static AstSetExpr div(AstSetExpr... divisors) { 137 return arithm(AstArithm.Op.Div, divisors); 138 } 139 140 public static AstSetExpr sum(AstSetExpr set) { 141 return new AstSum(set); 142 } 143 144 public static AstBoolExpr arithm(AstBoolArithm.Op op, AstBoolExpr... operands) { 145 if (operands.length == 1) { 146 return operands[0]; 147 } 148 return new AstBoolArithm(op, operands); 149 } 150 151 public static AstBoolExpr and(AstBoolExpr... operands) { 152 return arithm(AstBoolArithm.Op.And, operands); 153 } 154 155 public static AstBoolExpr ifOnlyIf(AstBoolExpr... operands) { 156 return arithm(AstBoolArithm.Op.IfOnlyIf, operands); 157 } 158 159 public static AstBoolExpr implies(AstBoolExpr... operands) { 160 return arithm(AstBoolArithm.Op.Implies, operands); 161 } 162 163 public static AstBoolExpr or(AstBoolExpr... operands) { 164 return arithm(AstBoolArithm.Op.Or, operands); 165 } 166 167 public static AstBoolExpr xor(AstBoolExpr... operands) { 168 return arithm(AstBoolArithm.Op.Xor, operands); 169 } 170 171 public static AstSetExpr diff(AstSetExpr left, AstSetExpr right) { 172 return new AstDifference(left, right); 173 } 174 175 public static AstSetExpr inter(AstSetExpr left, AstSetExpr right) { 176 return new AstIntersection(left, right); 177 } 178 179 public static AstSetExpr union(AstSetExpr left, AstSetExpr right) { 180 return new AstUnion(left, right); 181 } 182 183 public static AstBoolExpr membership(AstSetExpr member, AstMembership.Op op, AstSetExpr set) { 184 return new AstMembership(member, op, set); 185 } 186 187 public static AstBoolExpr in(AstSetExpr member, AstSetExpr set) { 188 return membership(member, AstMembership.Op.In, set); 189 } 190 191 public static AstBoolExpr notIn(AstSetExpr member, AstSetExpr set) { 192 return membership(member, AstMembership.Op.NotIn, set); 193 } 194 195 public static AstSetExpr ifThenElse(AstBoolExpr antecedent, AstSetExpr consequent, AstSetExpr alternative) { 196 return new AstTernary(antecedent, consequent, alternative); 197 } 198 199 public static AstBoolExpr ifThenElse(AstBoolExpr antecedent, AstBoolExpr consequent, AstBoolExpr alternative) { 200 return new AstIfThenElse(antecedent, consequent, alternative); 201 } 202 203 /** 204 * Downcast an expression. Highly unlikely you will ever need to call this 205 * method since the compiler will automatically insert casts where 206 * necessary. 207 * 208 * @param base the set expression 209 * @param target the casted type 210 * @return {@code base} downcasted to type {@code target} 211 */ 212 public static AstSetExpr downcast(AstSetExpr base, AstClafer target) { 213 return new AstDowncast(base, target); 214 } 215 216 /** 217 * Upcast an expression. Highly unlikely you will ever need to call this 218 * method since the compiler will automatically insert casts where 219 * necessary. 220 * 221 * @param base the set expression 222 * @param target the casted type 223 * @return {@code base} upcasted to type {@code target} 224 */ 225 public static AstSetExpr upcast(AstSetExpr base, AstAbstractClafer target) { 226 return new AstUpcast(base, target); 227 } 228 229 public static AstBoolExpr lone(AstClafer clafer) { 230 // Syntactic sugar. 231 return lone(global(clafer)); 232 } 233 234 public static AstBoolExpr lone(AstSetExpr set) { 235 // Syntactic sugar. 236 return lessThanEqual(card(set), constant(1)); 237 } 238 239 public static AstBoolExpr none(AstClafer clafer) { 240 // Syntactic sugar. 241 return none(global(clafer)); 242 } 243 244 public static AstBoolExpr none(AstSetExpr set) { 245 // Syntactic sugar. 246 return equal(card(set), constant(0)); 247 } 248 249 public static AstBoolExpr one(AstClafer clafer) { 250 // Syntactic sugar. 251 return one(global(clafer)); 252 } 253 254 public static AstBoolExpr one(AstSetExpr set) { 255 // Syntactic sugar. 256 return equal(card(set), constant(1)); 257 } 258 259 public static AstBoolExpr some(AstClafer clafer) { 260 // Syntactic sugar. 261 return some(global(clafer)); 262 } 263 264 public static AstBoolExpr some(AstSetExpr set) { 265 // Syntactic sugar. 266 return greaterThanEqual(card(set), constant(1)); 267 } 268 269 public static AstLocal local(String name) { 270 return new AstLocal(name); 271 } 272 273 public static AstDecl decl(boolean disjoint, AstLocal[] locals, AstSetExpr body) { 274 return new AstDecl(disjoint, locals, body); 275 } 276 277 public static AstDecl decl(AstLocal[] locals, AstSetExpr body) { 278 return decl(false, locals, body); 279 } 280 281 public static AstDecl decl(AstLocal local, AstSetExpr body) { 282 return decl(new AstLocal[]{local}, body); 283 } 284 285 public static AstDecl disjDecl(AstLocal[] locals, AstSetExpr body) { 286 return decl(true, locals, body); 287 } 288 289 public static AstBoolExpr quantify(Quantifier quantifier, AstDecl[] decls, AstBoolExpr body) { 290 return new AstQuantify(quantifier, decls, body); 291 } 292 293 public static AstBoolExpr quantify(Quantifier quantifier, AstDecl decl, AstBoolExpr body) { 294 return quantify(quantifier, new AstDecl[]{decl}, body); 295 } 296 297 public static AstBoolExpr all(AstDecl[] decls, AstBoolExpr body) { 298 return quantify(Quantifier.All, decls, body); 299 } 300 301 public static AstBoolExpr all(AstDecl decl, AstBoolExpr body) { 302 return quantify(Quantifier.All, decl, body); 303 } 304 305 public static AstBoolExpr lone(AstDecl[] decls, AstBoolExpr body) { 306 return quantify(Quantifier.Lone, decls, body); 307 } 308 309 public static AstBoolExpr lone(AstDecl decl, AstBoolExpr body) { 310 return quantify(Quantifier.Lone, decl, body); 311 } 312 313 public static AstBoolExpr none(AstDecl[] decls, AstBoolExpr body) { 314 return quantify(Quantifier.None, decls, body); 315 } 316 317 public static AstBoolExpr none(AstDecl decl, AstBoolExpr body) { 318 return quantify(Quantifier.None, decl, body); 319 } 320 321 public static AstBoolExpr one(AstDecl[] decls, AstBoolExpr body) { 322 return quantify(Quantifier.One, decls, body); 323 } 324 325 public static AstBoolExpr one(AstDecl decl, AstBoolExpr body) { 326 return quantify(Quantifier.One, decl, body); 327 } 328 329 public static AstBoolExpr some(AstDecl[] decls, AstBoolExpr body) { 330 return quantify(Quantifier.Some, decls, body); 331 } 332 333 public static AstBoolExpr some(AstDecl decl, AstBoolExpr body) { 334 return quantify(Quantifier.Some, decl, body); 335 } 336}