@Override public Transform visit(FQLProgram env, Proj e) { Functor l = e.l.accept(env, this); Functor r = e.r.accept(env, this); if (!l.source.equals(r.source)) { throw new RuntimeException("Source category does not match"); } if (!l.target.equals(r.target)) { throw new RuntimeException("Target category does not match"); } if (l.target.equals(FinSet.FinSet)) { if (e.proj1) { return Inst.get(l.source).first(l, r); } else { return Inst.get(l.source).second(l, r); } } else if (l.target.equals(FinCat.FinCat)) { if (e.proj1) { return FunCat.get(l.source).first(l, r); } else { return FunCat.get(l.source).second(l, r); } } else { throw new RuntimeException("report this error to ryan"); } }
@Override public Transform visit(FQLProgram env, Bool e) { Category c = e.cat.accept(env, this); if (e.b) { return Inst.get(c).tru(); } else { return Inst.get(c).fals(); } }
@Override public Transform visit(FQLProgram env, AndOrNotImplies e) { Category c = e.cat.accept(env, this); if (e.which.equals("not")) { return Inst.get(c).not(); } else { return Inst.get(c).andOrImplies(e.which); } }
@Override public Transform visit(FQLProgram env, fql_lib.decl.TransExp.Curry e) { Transform t = e.f.accept(env, this); if (t.source.source.isInfinite() || !t.source.target.equals(FinSet.FinSet)) { throw new RuntimeException("Cannot curry " + t); } if (e.useInst) { return Inst.get(t.source.source).curry(t); } else { return Inst.CURRY(t); } }
@Override public Functor visit(FQLProgram env, Curry e) { Functor f = e.f.accept(env, this); if (!f.source.isInfinite() && f.target.equals(FinSet.FinSet)) { return Inst.CURRY(f); } return FinCat.FinCat.curry(f); }
@Override public Functor visit(FQLProgram env, Uncurry e) { Functor f = e.F.accept(env, this); if (!f.source.isInfinite() && f.target instanceof Inst) { return Inst.UNCURRY(f); } throw new RuntimeException("Cannot uncurry " + f); }
@Override public Transform visit(FQLProgram env, fql_lib.decl.TransExp.Eval e) { Functor a = e.a.accept(env, this); Functor b = e.b.accept(env, this); if (!a.source.equals(b.source) || a.source.isInfinite() || !a.target.equals(FinSet.FinSet)) { throw new RuntimeException("Cannot eval " + a + " and " + b); } return Inst.get(a.source).eval(a, b); }
@Override public Transform visit(FQLProgram env, fql_lib.decl.TransExp.Zero e) { Functor F = e.f.accept(env, this); if (F.target.equals(FinSet.FinSet)) { return Inst.get(F.source).initial(F); } else if (F.target.equals(FinCat.FinCat)) { return FunCat.get(F.source).initial(F); } else { throw new RuntimeException("Error: Please send your file to Ryan."); } }
@Override public Functor visit(FQLProgram env, fql_lib.decl.FunctorExp.Zero e) { Category<?, ?> cat = e.cat.accept(env, this); Category<?, ?> amb = e.ambient.accept(env, this); if (amb.equals(FinSet.FinSet)) { return Inst.get(cat).initial(); } else if (amb.equals(FinCat.FinCat)) { return FunCat.get(cat).initial(); } else { throw new RuntimeException("Report this error to Ryan. Error: ambient category is " + amb); } }
@Override public Transform visit(FQLProgram env, Inj e) { Functor l = e.l.accept(env, this); Functor r = e.r.accept(env, this); if (!l.source.equals(r.source)) { throw new RuntimeException("Source category does not match"); } if (l.target.equals(FinSet.FinSet)) { if (e.inj1) { return Inst.get(l.source).inleft(l, r); } else { return Inst.get(l.source).inright(l, r); } } else if (l.target.equals(FinCat.FinCat)) { if (e.inj1) { return FunCat.get(l.source).inleft(l, r); } else { return FunCat.get(l.source).inright(l, r); } } else { throw new RuntimeException("Cannot inject: " + e + " to get a transform."); } }
@Override public Category visit(FQLProgram env, Exp e) { Category<?, ?> a = e.a.accept(env, this); Category<?, ?> b = e.b.accept(env, this); if (!a.isInfinite() && !b.isInfinite()) { return FinCat.FinCat.exp(a, b); } else if (!b.isInfinite() && a.equals(FinSet.FinSet)) { return Inst.get(b); } else if (!b.isInfinite() && a.equals(FinCat.FinCat)) { return FunCat.get(b); } else { throw new RuntimeException("Cannot compute category " + a + "^" + b); } }
@Override public Transform visit(FQLProgram env, fql_lib.decl.TransExp.CoProd e) { Transform l = e.l.accept(env, this); Transform r = e.r.accept(env, this); if (!l.target.equals(r.target)) { throw new RuntimeException("Target functors do not match"); } if (!l.target.source.equals(r.target.source)) { throw new RuntimeException("Categories do not match"); } if (l.source.target.equals(FinSet.FinSet)) { return Inst.get(l.target.source).match(l, r); } else if (l.source.target.equals(FinCat.FinCat)) { return FunCat.get(l.target.source).match(l, r); } else { throw new RuntimeException("Report this error to Ryan"); } }
@Override public Functor visit(FQLProgram env, Prod e) { Functor l = e.l.accept(env, this); Functor r = e.r.accept(env, this); if (FinSet.FinSet.equals(l.target) && FinSet.FinSet.equals(r.target)) { if (!l.source.equals(r.source)) { throw new RuntimeException("Source categories do not match"); } return Inst.get(l.source).product(l, r); } if (FinCat.FinCat.equals(l.target) && FinCat.FinCat.equals(r.target)) { if (!l.source.equals(r.source)) { throw new RuntimeException("Source categories do not match"); } return FunCat.get(l.source).product(l, r); } return FinCat.FinCat.pair(l, r); }
@Override public Functor visit(FQLProgram env, FunctorExp.Exp e) { Functor l = e.l.accept(env, this); Functor r = e.r.accept(env, this); if (FinSet.FinSet.equals(l.target) && FinSet.FinSet.equals(r.target)) { if (!l.source.equals(r.source)) { throw new RuntimeException("Source categories do not match"); } return Inst.get(l.source).exp(l, r); } if (FinCat.FinCat.equals(l.target) && FinCat.FinCat.equals(r.target)) { if (!l.source.equals(r.source)) { throw new RuntimeException("Source categories do not match"); } throw new RuntimeException("Not implemented yet"); // TODO // return FunCat.get(l.source).product(l, r); } throw new RuntimeException("Cannot exponentiate " + l + " and " + r); }
@Override public Transform visit(FQLProgram env, fql_lib.decl.TransExp.Iso e) { Functor l = e.l.accept(env, this); Functor r = e.r.accept(env, this); if (!l.source.equals(r.source)) { throw new RuntimeException( "Source categories do not match: " + l.source + "\nand\n" + r.source); } if (l.source.isInfinite()) { throw new RuntimeException("Source category must be finite."); } if (!l.target.equals(FinSet.FinSet)) { throw new RuntimeException("Target category must be Set."); } Optional<Pair<Transform, Transform>> k = Inst.get(l.source).iso(l, r); if (!k.isPresent()) { throw new RuntimeException("Not isomorphic: " + e.l + " and " + e.r); } if (e.lToR) { return k.get().first; } else { return k.get().second; } }
@Override public Functor visit(FQLProgram env, Prop e) { Category c = e.cat.accept(env, this); return Inst.get(c).prop(); }
@Override public Transform visit(FQLProgram env, Ker e) { Transform t = e.t.accept(env, this); return Inst.get(t.source.source).kernel(t); }