ggsimplify2(and(ti(truth,bool),ti(X,bool)),_,_,X) :- !.
ggsimplify2(and(ti(X,bool),ti(truth,bool)),_,_,X) :- !.
ggsimplify2(implies(_,ti(truth,bool)),_,_,truth) :- !.
ggsimplify2(ref(name('\\num',''),[]),_,_,basetype(set(num))) :- !.
ggsimplify2(power(ti(basetype(T),T)),_,_,basetype(set(T))) :- !.
ggsimplify2(pregen(name('\\finset',''),ti(basetype(T),T)),_,_,basetype(set(T))) :- !.
ggsimplify2(cross(List),_,_,basetype(set(tuple(Types)))) :-
all_basetypes(List,Types),!.
ggsimplify2(ingen(name('\\rel',''),ti(basetype(set(A)),_),ti(basetype(set(B)),_)),_,_,
basetype(set(tuple([A,B])))) :- !.
ggsimplify2(ref(Name,[]),set(given(Name)),Env,basetype(set(given(Name)))) :-
member(given(GivenEnv),Env),member(Name,GivenEnv),!.
ggsimplify2(comp(ti(body(_,[]),_),ti(nothing,none)),Type,_,basetype(Type)) :- !.
ggsimplify2(comp(BodyTi, ti(just(ResultTi),_)), _,_, comp(NewBody,ti(nothing,none))) :-
!, simplify_compset(BodyTi,ResultTi,NewBody).
ggsimplify2(mu(BodyTi, ti(just(ResultTi),_)), _,_, mu(NewBody,ti(nothing,none))) :-
!,simplify_compset(BodyTi,ResultTi,NewBody).
ggsimplify2(equal(ti(binding(B1),_),ti(binding(B2),_)), _,_, Result) :-
!, equal_bindings(B1,B2,ti(Result,bool)).
ggsimplify2(exists1(ti(body(Decl,Where),BType),Condition), _, Env, equal(Card,ti(number(1),num))) :-
!,
Card1 = ti(apply(Ref,Comp),num),
Ref = ti(ref(name('\\#',''),[]),set(tuple([SetType,num]))),
Comp = ti(comp(ti(body(Decl,NewWhere),BType),ti(nothing,none)),SetType),
compset_type_convert(BType,SetType),
append(Where,[Condition],NewWhere),
ggsimplify1(Card1,Env,Card).
ggsimplify2(inop(name('\\circ',''), A, B), _,_, inop(name('\\comp',''), B, A)) :- !.
ggsimplify2(apply(ti(ref(name('succ',''),[]),_), Arg), _,_,
inop(name('+',''),Arg, ti(number(1),num))) :- !.
ggsimplify2(body(Decls,Where), _,_, body(Decls,NewWhere)) :-
!,clean_wheret(Where,NewWhere).
ggsimplify2(member(Expr, ti(comp(Body,ti(nothing,none)),_)), _,_, Condition) :-
Body = ti(body([ti(decl([Var],_),_)],Wheres),_),
!,simplify_member(Expr,Var,Wheres,ti(Condition,bool)).
ggsimplify2(member(_,ti(basetype(_),_)), _,_, truth) :- !.
ggsimplify2(postop(name('\\star',''),ExprTi), RelType, _, inop(name('\\cup',''),TransCls,Id)) :-
RelType = set(tuple([T,T])),!,
TransCls = ti(postop(name('\\plus',''),ExprTi),RelType),
Id = ti(pregen(name('\\id',''),ti(basetype(set(T)),set(T))),RelType).
ggsimplify2(apply(ti(lambda(ti(body([ti(decl([Param],_),_)],[]),_),ExprTi),_),
ArgTi),_,_,
NewExpr) :-
!,replace_expression(ExprTi,Param,ArgTi,ti(NewExpr,_)).
ggsimplify2(bag(Expressions), BagType, _Env, apply(ItemsFun,Seq)) :- !,
BagType = set(tuple([X,num])), SeqType = set(tuple([num,X])),
ItemsFun = ti(ref(name('items',''),[]),set(tuple([BagType,SeqType]))),
Seq = ti(seq(Expressions),set(SeqType)).
ggsimplify2(pregen(name('\\bag',''),Set), _Type, _Env, ingen(name('\\pfun',''), Set, Nat1)) :-
ti_expr(Nat1,ref(name('\\nat','_1'),[])),
ti_type(Nat1,set(num)).
ggsimplify2(inop(name('\\bcount',''),Bag,Elem),Type,Env,IfThenElse) :-
!,create_bag_count(Bag,Elem,IfThenElse1), ggsimplify1(ti(IfThenElse1,Type),Env,ti(IfThenElse,_)).
ggsimplify2(apply(Count,Bag), _Type, _Env, lambda(Body,Expr)) :-
ti_expr(Count,ref(name('count',''),[])),!,
ti_type(Bag,BagType),
BagType = set(tuple([ArgType,num])),
z_counter('param__',P),Param=name(P,''),
Body = ti(body([ti(decl([Param],ti(basetype(set(ArgType)),set(ArgType))),none)],[]),
set(schema([field(Param,ArgType)]))),
ti_expr(RefParam,ref(Param,[])), ti_type(RefParam,ArgType),
create_bag_count(Bag,RefParam,IfThenElse),
ti_expr(Expr,IfThenElse), ti_type(Expr,num).
ggsimplify2(inop(name('\\otimes',''),Factor,Bag),Type,Env,Comp) :-
!,create_bag_otimes(Factor,Bag,Comp1), ggsimplify1(ti(Comp1,Type),Env,ti(Comp,_)).
ggsimplify2(inop(name('\\uminus',''),A,B),Type,Env,Comp) :-
!,create_bag_minus(A,B,Comp1), ggsimplify1(ti(Comp1,Type),Env,ti(Comp,_)).
ggsimplify2(inop(name('\\uplus',''),A,B),Type,Env,Comp) :-
!,create_bag_plus(A,B,Comp1), ggsimplify1(ti(Comp1,Type),Env,ti(Comp,_)).
ggsimplify2(inrel(name('\\inbag',''),Elem,Bag),_Type,_Env,member(Elem,Domain)) :-
!,make_z_domain(Bag,Domain).
ggsimplify2(inrel(name('\\subbageq',''),BagA,BagB),_Type,_Env,Pred) :-
!,create_subbag(BagA,BagB,Pred).
ggsimplify2(ref(CName,[]),freetype(FT),Env,ftconstant(FT,CName)) :-
is_ftconstant2(Env,FT,CName),!.
ggsimplify2(ref(CName,[]),set(tuple([ArgType,freetype(FT)])),Env,Lambda) :-
is_ftconstructor2(Env,FT,CName,DomSet),!,
Lambda1 = lambda(ti(body([ti(decl([Param],ti(basetype(set(ArgType)),set(ArgType))),none)],
[ti(member(ti(ref(Param,[]),ArgType),DomSet),bool)]),
set(schema([field(Param,ArgType)]))),
ti(ftconstructor(FT,CName,ti(ref(Param,[]),ArgType)),freetype(FT))),
z_counter('param__',P),Param=name(P,''),
ggsimplify1(ti(Lambda1,set(tuple([ArgType,freetype(FT)]))),Env,ti(Lambda,_)).
ggsimplify2(ref(FT,[]),set(freetype(FT)),Env,Result) :-
ftget(Env,FT,Arms,simpl),!,
z_counter('param__',P),Param=name(P,''),
Result1 = comp(ti(body([ti(decl([Param],ti(basetype(set(freetype(FT))),set(freetype(FT)))),none)],
Constraints),BType),ti(nothing,none)),
BType = set(schema([field(Param,freetype(FT))])),
create_constraints(Arms,FT,ti(ref(Param,[]),freetype(FT)),Constraints),
ggsimplify1(ti(Result1,set(freetype(FT))),Env,ti(Result,_)).
ggsimplify2(ref(FT,[]),set(freetype(FT)),Env,ref(Global,[])) :-
ftget(Env,FT,_,rec),!,
global_ft_constant(FT,Global).