equal_element(X,Y) :-
(var(X);var(Y)),!,X=Y.
equal_element(true,X) :- !,
( X=true -> true
; X=false -> fail
; add_error_fail(haskell_csp,'Type error in equality: ',true=X)
).
equal_element(false,X) :- !,
( X=false -> true
; X=true -> fail
; add_error_fail(haskell_csp,'Type error in equality: ',false=X)
).
equal_element(int(X),R) :- !,
(R=int(Y) -> X=Y
; add_error_fail(haskell_csp,'Type error in equality: ',int(X)=R)
).
equal_element(setFrom(X),R) :- !,
(R=setFrom(Y) -> X=Y
; is_a_set(R) -> fail
; add_error_fail(haskell_csp,'Type error in equality: ',setFrom(X)=R)
).
equal_element(setFromTo(X,Y),R) :- !,
(R=setFromTo(X2,Y2) -> X=X2,Y=Y2
; (R=setValue(_) ;R=setExp(_,_)) -> equal_sets(setFromTo(X,Y),R)
; is_a_set(R) -> fail % Set different for setValue and setExp
; add_error_fail(haskell_csp,'Type error in equality: ',setFromTo(X,Y)=R)
).
equal_element(setValue(X),R) :- !,
(R=setValue(Y) -> equal_setValue(X,Y)
; R=setFrom(_) -> fail % infinite set cannot be equal to finite one
; is_a_set(R) -> expand_symbolic_set(R,setValue(ER),equal_element), equal_setValue(X,ER)
; add_error_fail(haskell_csp,'Type error in equality: ',setValue(X)=R)
).
equal_element(list(X),R) :- !,
(R=list(Y) -> X=Y
;add_error_fail(haskell_csp,'Type error in equality: ',list(X)=R)
).
equal_element(na_tuple(X),R) :- !,
(R=na_tuple(Y) -> X=Y
;add_error_fail(haskell_csp,'Type error in equality: ',na_tuple(X)=R)
).
equal_element(tuple(X),R) :- !,
( R=tuple(Y) -> (X=Y ; equal_interleaved_dot_tuples(X,Y))
; R=record(C,A) -> X=[H|T], C=H, (T=A ; equal_interleaved_dot_tuples(T,A))
; add_error_fail(haskell_csp,'Type error in equality: ',tuple(X)=R)
).
equal_element(dotTuple(X),R) :- !,
( R=tuple(Y) -> (X=Y ; equal_interleaved_dot_tuples(X,Y))
; R=record(C,A) -> X=[H|T], C=H, (T=A ; equal_interleaved_dot_tuples(T,A))
; add_error_fail(haskell_csp,'Type error in equality: ',dotTuple(X)=R)
).
equal_element(record(C,A),R) :-
get_constructor_type(C,Type),!,
((R=record(C2,A2),get_constructor_type(C2,Type)) -> C=C2,(A=A2 ; equal_interleaved_dot_tuples(A,A2)) % missing subtype checks
; R=tuple([H|T]) -> (H=C,(T=A ; equal_interleaved_dot_tuples(A,T)))
; (atomic(R),get_constant_type(R,Type)) -> fail
; R=agent_call(_,_,_) -> force_evaluate_argument(R,Res),equal_element(record(C,A),Res)
; add_error_fail(haskell_csp,'Type error in equality: ',record(C,A)=R)
).
equal_element(X,R) :-
atomic(X),get_constant_type(X,Type),!,
((atomic(R),get_constant_type(R,Type)) -> X=R
;(R=record(C,_Args),get_constructor_type(C,Type)) -> fail
; add_error_fail(haskell_csp,'Type error in equality: ',X=R)
).
equal_element(Set,R) :-
is_a_set(Set),!,
expand_symbolic_set(Set,ES,equal_element),
equal_element(ES,R).
equal_element(X,Y) :- print(equal_element(X,Y)),nl,X=Y.