%{^
#include "ats_counter.cats" /* only needed for [ATS/Geizella] */
%}
staload Deb = "ats_debug.sats"
staload Err = "ats_error.sats"
staload Loc = "ats_location.sats"
typedef loc_t = $Loc.location_t
staload Lst = "ats_list.sats"
staload Syn = "ats_syntax.sats"
typedef funclo = $Syn.funclo
staload "ats_staexp2.sats"
staload "ats_staexp2_pprint.sats"
staload "ats_stadyncst2.sats"
staload "ats_trans3_env.sats"
staload "ats_staexp2_solve.sats"
#define THISFILENAME "ats_staexp2_solve.dats"
#define nil list_nil
#define cons list_cons
#define :: list_cons
overload = with $Lab.eq_label_label
overload = with $Stamp.eq_stamp_stamp
overload = with $Syn.eq_funclo_funclo
overload prerr with $Loc.prerr_location
fn prerr_loc_error3 (loc: loc_t): void =
($Loc.prerr_location loc; prerr ": error(3)")
fn prerr_loc_interror (loc: loc_t) = begin
$Loc.prerr_location loc; prerr ": INTERNAL ERROR (ats_staexp2_solve)"
end
datatype staerr =
| STAERR_s2exp_tyleq of (loc_t, s2exp, s2exp)
| STAERR_s2exp_equal of (loc_t, s2exp, s2exp)
| STAERR_funclo_equal of (loc_t, funclo, funclo)
| STAERR_s2eff_leq of (loc_t, s2eff, s2eff)
| STAERR_s2exp_linearity of (loc_t, s2exp)
viewtypedef staerrlst_vt = List_vt (staerr)
local
var the_staerrlst: staerrlst_vt = list_vt_nil ()
val p_the_staerrlst =
&the_staerrlst val (pfbox_the_staerrlst | ()) =
vbox_make_view_ptr {staerrlst_vt} (view@ (the_staerrlst) | p_the_staerrlst)
in
fn the_staerrlst_add
(x: staerr): void = let
prval vbox pf = pfbox_the_staerrlst
in
!p_the_staerrlst := list_vt_cons (x, !p_the_staerrlst)
end
fn the_staerrlst_get
(): staerrlst_vt = let
prval vbox pf = pfbox_the_staerrlst
val xs = !p_the_staerrlst
val () = !p_the_staerrlst := list_vt_nil ()
in
xs
end
end
fn prerr_staerr_funclo_equal
(loc: loc_t, fc1: funclo, fc2: funclo): void = begin
prerr_loc_error3 (loc);
prerr ": function/closure mismatch:\n";
prerr "The needed funclo kind is: "; $Syn.prerr_funclo fc2; prerr_newline ();
prerr "The actual funclo kind is: "; $Syn.prerr_funclo fc1; prerr_newline ();
end
fn prerr_staerr_s2exp_tyleq
(loc: loc_t, s2e1: s2exp, s2e2: s2exp): void = begin
prerr_loc_error3 (loc);
$Deb.debug_prerrf (": %s: s2exp_tyleq_solve", @(THISFILENAME));
prerr ": mismatch of static terms (tyleq):\n";
prerr "The needed term is: "; pprerr_s2exp s2e2; prerr_newline ();
prerr "The actual term is: "; pprerr_s2exp s2e1; prerr_newline ();
end
fn prerr_staerr_s2exp_equal
(loc: loc_t, s2e1: s2exp, s2e2: s2exp): void = begin
prerr_loc_error3 (loc);
$Deb.debug_prerrf (": %s: s2exp_equal_solve", @(THISFILENAME));
prerr ": mismatch of static terms (equal):\n";
prerr "The needed term is: "; pprerr_s2exp s2e2; prerr_newline ();
prerr "The actual term is: "; pprerr_s2exp s2e1; prerr_newline ();
end
fn prerr_staerr_s2eff_leq
(loc: loc_t, s2fe1: s2eff, s2fe2: s2eff): void = begin
prerr_loc_error3 (loc);
$Deb.debug_prerrf (": %s: s2exp_equal_solve", @(THISFILENAME));
prerr ": mismatch of effects:\n";
prerr "The needed term is: "; prerr_s2eff s2fe2; prerr_newline ();
prerr "The actual term is: "; prerr_s2eff s2fe1; prerr_newline ();
end
fn prerr_staerr_s2exp_linearity
(loc: loc_t, s2e: s2exp): void = begin
prerr_loc_error3 (loc);
$Deb.debug_prerrf (": %s: s2exp_equal_solve", @(THISFILENAME));
prerr ": mismatch of linearity:\n";
prerr "A nonlinear term is needed: "; pprerr_s2exp s2e; prerr_newline ();
end
fn prerr_the_staerrlst () = let
fun loop (xs: staerrlst_vt): void = case+ xs of
| ~list_vt_cons (x, xs) => let
val () = case+ x of
| STAERR_funclo_equal (loc, fc1, fc2) => prerr_staerr_funclo_equal (loc, fc1, fc2)
| STAERR_s2exp_equal (loc, s2e1, s2e2) => prerr_staerr_s2exp_equal (loc, s2e1, s2e2)
| STAERR_s2exp_tyleq (loc, s2e1, s2e2) => prerr_staerr_s2exp_tyleq (loc, s2e1, s2e2)
| STAERR_s2eff_leq (loc, s2fe1, s2fe2) => prerr_staerr_s2eff_leq (loc, s2fe1, s2fe2)
| STAERR_s2exp_linearity (loc, s2e) => prerr_staerr_s2exp_linearity (loc, s2e)
in
loop (xs)
end | ~list_vt_nil () => ()
in
loop (the_staerrlst_get ())
end
implement
funclo_equal_solve (loc0, fc1, fc2) =
if fc1 = fc2 then () else let
val () = prerr_staerr_funclo_equal (loc0, fc1, fc2)
in
$Err.abort {void} ()
end
implement
funclo_equal_solve_err (loc0, fc1, fc2, err) =
if fc1 = fc2 then () else let
val () = err := err + 1
val () = the_staerrlst_add (STAERR_funclo_equal (loc0, fc1, fc2))
in
end
implement
clokind_equal_solve_err (loc, knd1, knd2, err) =
if knd1 = knd2 then () else (err := err + 1)
implement
label_equal_solve_err (loc, l1, l2, err) =
if l1 = l2 then () else (err := err + 1)
implement
linearity_equal_solve_err (loc, lin1, lin2, err) =
if lin1 = lin2 then () else (err := err + 1)
implement
pfarity_equal_solve_err (loc, npf1, npf2, err) =
if npf1 = npf2 then () else (err := err + 1)
implement
refval_equal_solve_err (loc0, refval1, refval2, err) =
if refval1 = refval2 then () else (err := err + 1)
implement
stamp_equal_solve_err (loc, s1, s2, err) =
if s1 = s2 then () else (err := err + 1)
implement
tyreckind_equal_solve_err (loc, knd1, knd2, err) =
if knd1 = knd2 then () else (err := err + 1)
implement
s2exp_out_void_solve (loc0, s2e) = let
var err: int = 0
val s2e = s2exp_whnf s2e
val () = case+ s2e.s2exp_node of
| S2Ecst s2c =>
if s2cstref_cst_equ (Void_t0ype, s2c) then () else err := err + 1
| S2Eout _ => ()
| S2Etyrec (_knd, _npf, ls2es) => loop (loc0, ls2es) where {
fun loop
(loc0: loc_t, ls2es: labs2explst): void = case+ ls2es of
| LABS2EXPLSTcons (_, s2e, ls2es) => let
val () = s2exp_out_void_solve (loc0, s2e) in loop (loc0, ls2es)
end | LABS2EXPLSTnil () => ()
} | _ => (err := err + 1)
in
if err > 0 then begin
prerr_loc_error3 (loc0);
prerr ": the type ["; prerr s2e; prerr "] is expected to be empty.";
prerr_newline ();
$Err.abort {void} ()
end end
implement
s2exp_out_void_solve_at (loc0, s2e_at) = begin
case+ un_s2exp_at_viewt0ype_addr_view s2e_at of
| ~Some_vt s2ts2a => s2exp_out_void_solve (loc0, s2ts2a.0)
| ~None_vt () => begin
prerr_loc_error3 (loc0);
prerr ": the type ["; prerr s2e_at; prerr "] is expected to be an @-view.";
prerr_newline ();
$Err.abort {void} ()
end end
fn s2exp_nonlin_test_err (
loc: loc_t, s2e: s2exp, err: &int
) : void =
if s2exp_is_linear s2e then let
val () = err := err + 1
val () = the_staerrlst_add (STAERR_s2exp_linearity (loc, s2e))
in
end
fn s2exp_equal_solve_abscon_err (
loc0: loc_t
, s2e1: s2exp, s2e2: s2exp, err: &int
) : void = let
fun aux_solve ( loc0: loc_t
, s2e1: s2exp, s2e2: s2exp, err: &int
) : void = begin
case+ (s2e1.s2exp_node, s2e2.s2exp_node) of
| (S2Eapp (s2e11, s2es12), S2Eapp (s2e21, s2es22)) => let
val () = aux_solve (loc0, s2e11, s2e21, err)
val () = s2explst_equal_solve_err (loc0, s2es12, s2es22, err)
in
end | (_, _) => ()
end
fun aux_check ( s2e1: s2exp, s2e2: s2exp
) : bool = begin
case+ (s2e1.s2exp_node, s2e2.s2exp_node) of
| (S2Ecst s2c1, S2Ecst s2c2) => eq_s2cst_s2cst (s2c1, s2c2)
| (S2Eapp (s2e1, _), S2Eapp (s2e2, _)) => aux_check (s2e1, s2e2)
| (_, _ ) => false
end
val coneq = aux_check (s2e1, s2e2)
in
if coneq then aux_solve (loc0, s2e1, s2e2, err) else (err := err + 1)
end
fn s2exp_equal_solve_appvar_err (
loc0: loc_t
, s2e1: s2exp, s2e2: s2exp, err: &int
) : void = aux (loc0, s2e1, s2e2, err) where {
fun aux
(loc0: loc_t, s2e1: s2exp, s2e2: s2exp, err: &int)
: void = begin
case+ (s2e1.s2exp_node, s2e2.s2exp_node) of
| (S2Eapp (s2e11, s2es12), S2Eapp (s2e21, s2es22)) => begin
aux (loc0, s2e11, s2e21, err);
s2explst_equal_solve_err (loc0, s2es12, s2es22, err)
end | (_, _) => ()
end }
implement
s2exp_equal_solve (loc0, s2e10, s2e20) = let
var err: int = 0
val () = s2exp_equal_solve_err (loc0, s2e10, s2e20, err)
in
if err > 0 then let
val () = prerr_the_staerrlst () in $Err.abort {void} ()
end end
implement
s2exp_equal_solve_err (loc0, s2e10, s2e20, err) = let
val err0 = err
val s2e10 = s2exp_whnf s2e10 and s2e20 = s2exp_whnf s2e20
val () = case+ (s2e10.s2exp_node, s2e20.s2exp_node) of
| (S2EVar s2V1, _) => begin
s2exp_equal_solve_Var_err (loc0, s2V1, s2e10, s2e20, err)
end | (_, S2EVar s2V2) => begin
s2exp_equal_solve_Var_err (loc0, s2V2, s2e20, s2e10, err)
end
| (S2Ecrypt s2e1, s2en20) => begin case+ s2en20 of
| S2Ecrypt s2e2 => s2exp_equal_solve_err (loc0, s2e1, s2e2, err)
| _ => (err := err + 1)
end | (S2Ecst s2c1, s2en20) => begin case+ s2en20 of
| S2Ecst s2c2 => begin
if eq_s2cst_s2cst (s2c1, s2c2) then () else (err := err + 1)
end | _ => begin
trans3_env_add_eqeq (loc0, s2e10, s2e20)
end end
| (S2Eread (_v1, s2e1), s2en20) => begin
case+ s2en20 of
| S2Eread (_v2, s2e2) => begin
s2exp_equal_solve_err (loc0, _v2, _v1, err);
s2exp_equal_solve_err (loc0, s2e1, s2e2, err)
end | _ => (err := err + 1)
end | (S2Esizeof s2e1, s2en20) => begin
case+ s2en20 of
| S2Esizeof s2e2 => begin
s2exp_size_equal_solve_err (loc0, s2e1, s2e2, err)
end | _ => (err := err + 1)
end | (S2Etyarr (s2e1_elt, s2ess1_dim), s2en20) => begin
case+ s2en20 of
| S2Etyarr (s2e2_elt, s2ess2_dim) => begin
s2exp_equal_solve_err (loc0, s2e1_elt, s2e2_elt, err);
s2explstlst_equal_solve_err (loc0, s2ess1_dim, s2ess2_dim, err)
end | _ => (err := err + 1)
end | (S2Etyrec (knd1, npf1, ls2es1), s2en20) => begin
case+ s2en20 of
| S2Etyrec (knd2, npf2, ls2es2) => begin
tyreckind_equal_solve_err (loc0, knd1, knd2, err);
pfarity_equal_solve_err (loc0, npf1, npf2, err);
labs2explst_equal_solve_err (loc0, ls2es1, ls2es2, err)
end | _ => (err := err + 1)
end | (S2Ewth (s2e1, wths2es1), s2en20) => begin
case+ s2en20 of
| S2Ewth (s2e2, wths2es2) => begin
s2exp_equal_solve_err (loc0, s2e1, s2e2, err);
wths2explst_equal_solve_err (loc0, wths2es1, wths2es2, err)
end | _ => (err := err + 1)
end | (_, _) when
s2exp_is_abscon s2e10 andalso s2exp_is_abscon s2e20 => begin
s2exp_equal_solve_abscon_err (loc0, s2e10, s2e20, err)
end | (_, _) when s2exp_is_impredicative s2e10 => begin
s2exp_tyleq_solve_err (loc0, s2e10, s2e20, err);
s2exp_tyleq_solve_err (loc0, s2e20, s2e10, err)
end | (_, _) when s2exp_syneq (s2e10, s2e20) => ()
| (_, _) => trans3_env_add_eqeq (loc0, s2e10, s2e20)
val () = if err > err0 then
the_staerrlst_add (STAERR_s2exp_equal (loc0, s2e10, s2e20))
in
end
implement
s2explst_equal_solve_err
(loc0, s2es10, s2es20, err) = let
fun aux ( s2es1: s2explst, s2es2: s2explst, err: &int
) :<cloref1> void =
case+ (s2es1, s2es2) of
| (s2e1 :: s2es1, s2e2 :: s2es2) => begin
s2exp_equal_solve_err (loc0, s2e1, s2e2, err);
aux (s2es1, s2es2, err)
end | (nil _, nil _) => ()
| (cons _, nil _) => (err := err + 1)
| (nil _, cons _) => (err := err + 1)
in
aux (s2es10, s2es20, err)
end
implement
labs2explst_equal_solve_err
(loc0, ls2es10, ls2es20, err) = let
fun aux (
ls2es1: labs2explst
, ls2es2: labs2explst
, err: &int
) :<cloref1> void = begin
case+ (ls2es1, ls2es2) of
| (LABS2EXPLSTcons (l1, s2e1, ls2es1),
LABS2EXPLSTcons (l2, s2e2, ls2es2)) => begin
label_equal_solve_err (loc0, l1, l2, err);
s2exp_equal_solve_err (loc0, s2e1, s2e2, err);
aux (ls2es1, ls2es2, err)
end | (LABS2EXPLSTnil _, LABS2EXPLSTnil _) => ()
| (LABS2EXPLSTcons _, LABS2EXPLSTnil _) => (err := err + 1)
| (LABS2EXPLSTnil _, LABS2EXPLSTcons _) => (err := err + 1)
end in
aux (ls2es10, ls2es20, err)
end
implement
wths2explst_equal_solve_err
(loc0, wths2es10, wths2es20, err) = let
fun aux (
wths2es1: wths2explst
, wths2es2: wths2explst
, err: &int
) :<cloref1> void = begin
case+ (wths2es1, wths2es2) of
| (WTHS2EXPLSTcons_some (refval1, s2e1, wths2es1),
WTHS2EXPLSTcons_some (refval2, s2e2, wths2es2)) => begin
s2exp_equal_solve_err (loc0, s2e1, s2e2, err);
aux (wths2es1, wths2es2, err)
end | (WTHS2EXPLSTcons_none wths2es1,
WTHS2EXPLSTcons_none wths2es2) => begin
aux (wths2es1, wths2es2, err)
end | (WTHS2EXPLSTnil _, WTHS2EXPLSTnil _) => ()
| (_, _) => (err := err + 1)
end in
aux (wths2es10, wths2es20, err)
end
implement
s2explstlst_equal_solve_err
(loc0, s2ess10, s2ess20, err) = let
fun aux (
s2ess1: s2explstlst, s2ess2: s2explstlst, err: &int
) :<cloref1> void = begin case+ (s2ess1, s2ess2) of
| (cons (s2es1, s2ess1), cons (s2es2, s2ess2)) => let
val () = s2explst_equal_solve_err (loc0, s2es1, s2es2, err)
in
aux (s2ess1, s2ess2, err)
end | (nil (), nil ()) => ()
| (_, _) => (err := err + 1)
end in
aux (s2ess10, s2ess20, err)
end
implement
s2exp_size_equal_solve_err
(loc0, s2e10, s2e20, err) = let
val s2ze10 = s2zexp_make_s2exp s2e10
and s2ze20 = s2zexp_make_s2exp s2e20
val test = s2zexp_syneq (s2ze10, s2ze20)
in
if test then () else (err := err + 1)
end
implement
s2exp_tyleq_solve_err (loc0, s2e10, s2e20, err) = let
val err0 = err
val s2e10 = s2exp_whnf s2e10 and s2e20 = s2exp_whnf s2e20
val () = case+ (s2e10.s2exp_node, s2e20.s2exp_node) of
| (S2EVar s2V1, S2EVar s2V2) when eq_s2Var_s2Var (s2V1, s2V2) => ()
| (S2EVar s2V1, _) => begin
s2exp_tyleq_solve_Var_l_err (loc0, s2V1, s2e10, s2e20, err)
end | (_, S2EVar s2V2) => begin
s2exp_tyleq_solve_Var_r_err (loc0, s2e10, s2V2, s2e20, err)
end
| (s2en10, S2Etop (knd2, s2e2)) => begin case+ knd2 of
| 0 => begin
if s2exp_is_nonlin s2e10 then begin
s2exp_size_equal_solve_err (loc0, s2e10, s2e20, err)
end else (err := err + 1) end | _ => begin case+ s2en10 of
| S2Etop (knd1, s2e1) =>
if knd1 = 1 then begin
s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
end else (err := err + 1) | _ => (err := err + 1)
end
end
| (S2Euni _, _) => let
val () = trans3_env_push_sta ()
val s2e2 = s2exp_absuni_and_add (loc0, s2e20)
val s2e1 = s2exp_uni_instantiate_all (loc0, s2e10)
val () = s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
in
trans3_env_pop_sta_and_add_none (loc0)
end | (_, S2Eexi _) => let
val () = trans3_env_push_sta ()
val s2e1 = s2exp_opnexi_and_add (loc0, s2e10)
val s2e2 = s2exp_exi_instantiate_all (loc0, s2e20)
val () = s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
in
trans3_env_pop_sta_and_add_none (loc0)
end | (_, S2Euni _) => let
val () = trans3_env_push_sta ()
val s2e2 = s2exp_absuni_and_add (loc0, s2e20)
val () = s2exp_tyleq_solve_err (loc0, s2e10, s2e2, err)
in
trans3_env_pop_sta_and_add_none (loc0)
end | (S2Eexi _, _) => let
val () = trans3_env_push_sta ()
val s2e1 = s2exp_opnexi_and_add (loc0, s2e10)
val () = s2exp_tyleq_solve_err (loc0, s2e1, s2e20, err)
in
trans3_env_pop_sta_and_add_none (loc0)
end | (S2Eapp (s2e1_fun, s2es1_arg), s2en20) => begin
case+ s2en20 of
| S2Eapp (s2e2_fun, s2es2_arg) => begin
case+ (
s2e1_fun.s2exp_node, s2e2_fun.s2exp_node
) of
| (S2Ecst s2c1_fun, S2Ecst s2c2_fun) => begin
if s2cst_is_eqsup (s2c1_fun, s2c2_fun) then begin
case+ s2cst_argvar_get s2c1_fun of
| Some argvarlst => begin
s2explst_tyleq_solve_argvarlst_err
(loc0, s2es1_arg, s2es2_arg, argvarlst, err)
end | None () => begin
s2explst_equal_solve_err (loc0, s2es1_arg, s2es2_arg, err)
end end else begin
err := err + 1
end end
| (_, _) => begin
s2exp_equal_solve_err (loc0, s2e1_fun, s2e2_fun, err);
s2explst_equal_solve_err (loc0, s2es1_arg, s2es2_arg, err)
end
end | S2Ecst s2c2 => begin case+ s2e1_fun.s2exp_node of
| S2Ecst s2c1_fun => begin
if s2cst_is_eqsup (s2c1_fun, s2c2) then () else (err := err + 1)
end | _ => (err := err + 1)
end | _ => (err := err + 1)
end | (S2Eclo (knd1, s2e1), s2en20) => begin case+ s2en20 of
| S2Eclo (knd2, s2e2) => let
val () = clokind_equal_solve_err (loc0, knd1, knd2, err)
in
s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
end | _ => (err := err + 1)
end | (S2Ecrypt s2e1, s2en20) => begin case+ s2en20 of
| S2Ecrypt s2e2 => s2exp_equal_solve_err (loc0, s2e1, s2e2, err)
| _ => (err := err + 1)
end | (S2Ecst s2c1, s2en20) => begin case+ s2en20 of
| S2Ecst s2c2 => begin
if s2cst_is_eqsup (s2c1, s2c2) then () else (err := err + 1)
end
| _ => (err := err + 1)
end | (S2Edatconptr (d2c1, s2es1), s2en20) => begin case+ s2en20 of
| S2Edatconptr (d2c2, s2es2) => begin
if d2c1 = d2c2 then begin
s2explst_equal_solve_err (loc0, s2es1, s2es2, err)
end else begin
err := err + 1
end
end | _ => (err := err + 1)
end | (S2Efun (fc1, lin1, s2fe1, npf1, s2es1_arg, s2e1_res), s2en20) => begin
case+ s2en20 of
| S2Efun (
fc2, lin2, s2fe2, npf2, s2es2_arg, s2e2_res
) => () where {
val () = funclo_equal_solve_err (loc0, fc1, fc2, err)
val () = linearity_equal_solve_err (loc0, lin1, lin2, err)
val () = pfarity_equal_solve_err (loc0, npf1, npf2, err)
val () = s2eff_leq_solve_err (loc0, s2fe1, s2fe2, err)
val () = s2explst_tyleq_solve_err (loc0, s2es2_arg, s2es1_arg, err)
val () = s2exp_tyleq_solve_err (loc0, s2e1_res, s2e2_res, err)
} | S2Eclo (knd2, s2e2_fun) => let
val () = case+ fc1 of
| $Syn.FUNCLOclo knd1 => begin
clokind_equal_solve_err (loc0, knd1, knd2, err)
end | _ => (err := err + 1)
val s2t1: s2rt = if lin1 > 0 then s2rt_viewtype else s2rt_type
val s2e1_fun = s2exp_fun_srt
(s2t1, $Syn.FUNCLOfun (), lin1, s2fe1, npf1, s2es1_arg, s2e1_res)
in
s2exp_tyleq_solve_err (loc0, s2e1_fun, s2e2_fun, err)
end | _ => (err := err + 1)
end
| (S2Eread (_v1, s2e1), s2en20) => begin case+ s2en20 of
| S2Eread (_v2, s2e2) => begin
s2exp_tyleq_solve_err (loc0, _v2, _v1, err);
s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
end | _ => (err := err + 1)
end | (S2Erefarg (refval1, s2e1), s2en20) => begin case+ s2en20 of
| S2Erefarg (refval2, s2e2) => begin
refval_equal_solve_err (loc0, refval1, refval2, err);
s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
end | _ => (err := err + 1)
end | (S2Etyarr (s2e1_elt, s2ess1_dim), s2en20) => begin case+ s2en20 of
| S2Etyarr (s2e2_elt, s2ess2_dim) => () where {
val () = s2exp_tyleq_solve_err (loc0, s2e1_elt, s2e2_elt, err)
val () = s2explstlst_equal_solve_err (loc0, s2ess1_dim, s2ess2_dim, err)
} | _ => (err := err + 1)
end | (S2Etylst s2es1, s2en20) => begin case+ s2en20 of
| S2Etylst s2es2 => begin
s2explst_tyleq_solve_err (loc0, s2es1, s2es2, err)
end | _ => (err := err + 1)
end | (S2Etyrec (knd1, npf1, ls2es1), s2en20) => begin
case+ s2en20 of
| S2Etyrec (knd2, npf2, ls2es2) => () where {
val () = tyreckind_equal_solve_err (loc0, knd1, knd2, err)
val () = pfarity_equal_solve_err (loc0, npf1, npf2, err)
val () = labs2explst_tyleq_solve_err (loc0, ls2es1, ls2es2, err)
} | S2Evararg s2e2 => let
val s2e1 = s2exp_tylst (s2es) where {
fun aux (
loc0: loc_t, ls2es: labs2explst, err: &int
) : s2explst = case+ ls2es of
| LABS2EXPLSTcons (_, s2e, ls2es) => let
val () = s2exp_nonlin_test_err (loc0, s2e, err)
val s2es = aux (loc0, ls2es, err)
in
list_cons (s2e, s2es)
end | LABS2EXPLSTnil () => list_nil ()
val s2es = aux (loc0, ls2es1, err)
} val () = tyreckind_equal_solve_err (loc0, knd1, TYRECKINDflt0, err)
val () = pfarity_equal_solve_err (loc0, npf1, 0, err)
in
s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
end | _ => (err := err + 1)
end | (S2Eunion (s1, s2i1, ls2es1), s2en20) => begin case+ s2en20 of
| S2Eunion (s2, s2i2, ls2es2) => let
val () = stamp_equal_solve_err (loc0, s1, s2, err)
val () = s2exp_equal_solve_err (loc0, s2i1, s2i2, err) in
labs2explst_tyleq_solve_err (loc0, ls2es1, ls2es2, err)
end | _ => (err := err + 1)
end | (S2Evar s2v1, s2en20) => begin case+ s2en20 of
| S2Evar s2v2 =>
if s2v1 = s2v2 then () else (err := err + 1)
| _ => (err := err + 1)
end | (S2Evararg s2e1, s2en20) => begin
case+ s2en20 of
| S2Evararg s2e2 => s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
| _ => (err := err + 1)
end | (S2Ewth (s2e1, wths2es1), s2en20) => begin
case+ s2en20 of
| S2Ewth (s2e2, wths2es2) => () where {
val () = s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
val () = wths2explst_tyleq_solve_err (loc0, wths2es1, wths2es2, err)
} | _ => (err := err + 1)
end | (_, _) when s2exp_syneq (s2e10, s2e20) => ()
| (_, _) => begin
err := err + 1
end val () = if err > err0 then
the_staerrlst_add (STAERR_s2exp_tyleq (loc0, s2e10, s2e20))
in
end
implement
s2explst_tyleq_solve_err
(loc0, s2es10, s2es20, err) = let
fun aux (s2es1: s2explst, s2es2: s2explst, err: &int)
:<cloptr1> void = begin case+ (s2es1, s2es2) of
| (s2e1 :: s2es1, s2e2 :: s2es2) => begin
s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err);
aux (s2es1, s2es2, err)
end | (nil _, nil _) => ()
| (cons _, nil _) => (err := err + 1)
| (nil _, cons _) => (err := err + 1)
end in
aux (s2es10, s2es20, err)
end
implement
s2explst_tyleq_solve_argvarlst_err
(loc0, s2es1, s2es2, argvarlst, err) = begin
case+ argvarlst of
| cons (argvar, argvarlst) => begin case+ (s2es1, s2es2) of
| (s2e1 :: s2es1, s2e2 :: s2es2) => let
val pol = argvar.2
val () = begin
if pol > 0 then begin
s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err)
end else if pol < 0 then begin
s2exp_tyleq_solve_err (loc0, s2e2, s2e1, err)
end else begin
s2exp_equal_solve_err (loc0, s2e1, s2e2, err)
end end in
s2explst_tyleq_solve_argvarlst_err (loc0, s2es1, s2es2, argvarlst, err)
end | (_, _) => begin
prerr_loc_interror loc0;
prerr ": s2explst_tyleq_solve_argvarlst_err"; prerr_newline ();
$Err.abort {void} ()
end end | nil () => ()
end
implement
labs2explst_tyleq_solve_err
(loc0, ls2es10, ls2es20, err) = let
fun aux (ls2es1: labs2explst, ls2es2: labs2explst, err: &int)
:<cloptr1> void = begin case+ (ls2es1, ls2es2) of
| (LABS2EXPLSTcons (l1, s2e1, ls2es1),
LABS2EXPLSTcons (l2, s2e2, ls2es2)) => begin
label_equal_solve_err (loc0, l1, l2, err);
s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err);
aux (ls2es1, ls2es2, err)
end
| (LABS2EXPLSTnil _, LABS2EXPLSTnil _) => ()
| (LABS2EXPLSTcons _, LABS2EXPLSTnil _) => (err := err + 1)
| (LABS2EXPLSTnil _, LABS2EXPLSTcons _) => (err := err + 1)
end in
aux (ls2es10, ls2es20, err)
end
implement
wths2explst_tyleq_solve_err
(loc0, wths2es10, wths2es20, err) = let
fun aux (wths2es1: wths2explst, wths2es2: wths2explst, err: &int)
:<cloptr1> void = begin case+ (wths2es1, wths2es2) of
| (WTHS2EXPLSTcons_some (refval1, s2e1, wths2es1),
WTHS2EXPLSTcons_some (refval2, s2e2, wths2es2)) => begin
s2exp_tyleq_solve_err (loc0, s2e1, s2e2, err);
aux (wths2es1, wths2es2, err)
end | (WTHS2EXPLSTcons_none wths2es1,
WTHS2EXPLSTcons_none wths2es2) => begin
aux (wths2es1, wths2es2, err)
end | (WTHS2EXPLSTnil _, WTHS2EXPLSTnil _) => ()
| (_, _) => (err := err + 1)
end in
aux (wths2es10, wths2es20, err)
end
implement
s2eff_leq_solve (loc0, s2fe1, s2fe2) = let
var err: int = 0
val () = s2eff_leq_solve_err (loc0, s2fe1, s2fe2, err)
in
if err > 0 then begin
prerr_loc_error3 (loc0);
prerr ": the computed effects [";
prerr s2fe1;
prerr "] does not match the expected effects [";
prerr s2fe2;
prerr "].";
prerr_newline ();
$Err.abort {void} ()
end end
implement
s2eff_leq_solve_err (loc0, s2fe1, s2fe2, err) = let
val ans = (case+ s2fe2 of
| S2EFFset (effs, s2es2) => begin case+ s2es2 of
| cons (s2e2, nil ()) => let
val s2e2_whnf = s2exp_whnf s2e2
in
case+ s2e2_whnf.s2exp_node of
| S2EVar s2V2 => let
val s2e1 = s2exp_eff s2fe1
in
s2exp_equal_solve_Var_err (loc0, s2V2, s2e2, s2e1, err); 0
end | _ => 1
end
| _ => 1
end | _ => 1
) : int in
if ans > 0 then
if s2eff_contain_s2eff (s2fe2, s2fe1) then () else let
val () = the_staerrlst_add (STAERR_s2eff_leq (loc0, s2fe1, s2fe2))
in
err := err + 1
end end
fun s2exp_tyleq_solve_lbs_err
(loc0: loc_t, lbs: s2Varboundlst, s2e: s2exp, err: &int): void =
case+ lbs of
| cons (lb, lbs) => let
val lb_s2e = s2Varbound_val_get lb
val () = s2exp_tyleq_solve_err (loc0, lb_s2e, s2e, err)
in
s2exp_tyleq_solve_lbs_err (loc0, lbs, s2e, err)
end | nil () => ()
fun s2exp_tyleq_solve_ubs_err
(loc0: loc_t, s2e: s2exp, ubs: s2Varboundlst, err: &int): void =
case+ ubs of
| cons (ub, ubs) => let
val ub_s2e = s2Varbound_val_get ub
val () = s2exp_tyleq_solve_err (loc0, s2e, ub_s2e, err)
in
s2exp_tyleq_solve_ubs_err (loc0, s2e, ubs, err)
end | nil () => ()
implement
s2exp_equal_solve_Var_err (loc0, s2V1, s2e1, s2e2, err) = let
var s2cs: s2cstlst = S2CSTLSTnil () and s2vs: s2varlst = list_nil ()
val ans = s2Var_s2exp_occurs (s2V1, s2e2, s2cs, s2vs)
in
case+ (ans, s2cs, s2vs) of
| (0, S2CSTLSTnil (), list_nil ()) => let
val s2t1 = s2Var_srt_get s2V1 and s2t2 = s2e2.s2exp_srt
in
if (s2t2 <= s2t1) then let
val () = s2Var_srt_set (s2V1, s2t2)
val () = s2exp_srt_set (s2e1, s2t2)
val () = s2Var_link_set (s2V1, Some s2e2)
in
s2exp_tyleq_solve_lbs_err (loc0, s2Var_lbs_get s2V1, s2e2, err);
s2exp_tyleq_solve_ubs_err (loc0, s2e2, s2Var_ubs_get s2V1, err);
end else begin
prerr_loc_error3 (loc0);
$Deb.debug_prerrf (": %s: s2exp_equal_solve_Var_err", @(THISFILENAME));
prerr ": sort mismatch: the sort of [";
prerr s2V1;
prerr "] is [";
prerr s2t1;
prerr "], but the sort of its solution is [";
prerr s2t2;
prerr "].";
prerr_newline ();
err := err + 1
end end | (_, _, _) => let
in
trans3_env_add_eqeq (loc0, s2e1, s2e2)
end end
implement s2exp_tyleq_solve_Var_l_err
(loc0, s2V1, s2e1, s2e2, err) = let
val lbs = s2Var_lbs_get s2V1 and ubs = s2Var_ubs_get s2V1
var s2cs: s2cstlst = S2CSTLSTnil () and s2vs: s2varlst = list_nil ()
val ans = s2Var_s2exp_occurs (s2V1, s2e2, s2cs, s2vs)
in
case+ (ans, s2cs, s2vs) of
| (0, S2CSTLSTnil (), list_nil ()) => let
val () = s2exp_tyleq_solve_lbs_err (loc0, lbs, s2e2, err)
val ub = s2Varbound_make (loc0, s2e2)
in
s2Var_ubs_set (s2V1, list_cons (ub, ubs))
end | (_, _, _) => let
in
trans3_env_add_tyleq (loc0, s2e1, s2e2)
end end
implement s2exp_tyleq_solve_Var_r_err
(loc0, s2e1, s2V2, s2e2, err) = let
val lbs = s2Var_lbs_get s2V2 and ubs = s2Var_ubs_get s2V2
var s2cs: s2cstlst = S2CSTLSTnil () and s2vs: s2varlst = list_nil ()
val ans = s2Var_s2exp_occurs (s2V2, s2e1, s2cs, s2vs)
in
case+ (ans, s2cs, s2vs) of
| (0, S2CSTLSTnil (), list_nil ()) => let
val () = s2exp_tyleq_solve_ubs_err (loc0, s2e1, ubs, err)
val s2t1 = s2e1.s2exp_srt
val s2t2 = s2Var_srt_get (s2V2)
val () = if s2t1 <= s2t2 then () else begin
prerr_loc_error3 (loc0);
$Deb.debug_prerrf (": %s: s2exp_equal_solve_Var_err", @(THISFILENAME));
prerr ": sort mismatch: the sort of [s2V(";
prerr s2V2;
prerr ")] is [";
prerr s2t2;
prerr "], but the sort of its lower bound is [";
prerr s2t1;
prerr "].";
prerr_newline ();
err := err + 1
end val lb = s2Varbound_make (loc0, s2e1)
in
s2Var_lbs_set (s2V2, list_cons (lb, lbs))
end
| (_, _, _) => let
in
trans3_env_add_tyleq (loc0, s2e1, s2e2)
end
end
implement
s2exp_tyleq_solve (loc0, s2e10, s2e20) = let
var err: int = 0
val () = s2exp_tyleq_solve_err (loc0, s2e10, s2e20, err)
in
if err > 0 then let
val () = prerr_the_staerrlst () in $Err.abort {void} ()
end end
implement
s2explst_arg_tyleq_solve (loc0, s2es10, s2es20) = let
fun aux {n:nat}
(loc0: loc_t, s2es1: list (s2exp, n), s2es2: list (s2exp, n))
: void = case+ s2es1 of
| (cons (s2e1, s2es1)) => let
val+ cons (s2e2, s2es2) = s2es2
val s2e2 = un_s2exp_refarg_arg s2e2
in
s2exp_tyleq_solve (loc0, s2e1, s2e2); aux (loc0, s2es1, s2es2)
end
| nil () => ()
val [sgn:int] sgn = $Lst.list_length_compare (s2es10, s2es20)
val () = (
if (sgn <> 0) then begin
prerr_loc_error3 (loc0);
$Deb.debug_prerrf (": %s: s2exp_arg_tyleq_solve", @(THISFILENAME));
if sgn > 0 then prerr ": this function call needs more arguments.";
if sgn < 0 then prerr ": this function call needs less arguments.";
prerr_newline ();
$Err.abort {void} ();
assert (sgn = 0)
end else begin
() end
) : [sgn==0] void
in
aux (loc0, s2es10, s2es20)
end
fn s2exp_hypo_equal_solve_con
(loc0: loc_t, s2e1: s2exp, s2e2: s2exp): void = let
fun aux_solve (loc0: loc_t, s2e1: s2exp, s2e2: s2exp): void =
case+ (s2e1.s2exp_node, s2e2.s2exp_node) of
| (S2Eapp (s2e1_fun, s2es1_arg), S2Eapp (s2e2_fun, s2es2_arg)) => begin
aux_solve (loc0, s2e1_fun, s2e2_fun);
s2explst_hypo_equal_solve (loc0, s2es1_arg, s2es2_arg)
end
| (_, _) => ()
fun aux_check (s2e1: s2exp, s2e2: s2exp): bool =
case+ (s2e1.s2exp_node, s2e2.s2exp_node) of
| (S2Ecst s2c1, S2Ecst s2c2) => eq_s2cst_s2cst (s2c1, s2c2)
| (S2Eapp (s2e1, _), S2Eapp (s2e2, _)) => aux_check (s2e1, s2e2)
| (_, _) => false
in
if aux_check (s2e1, s2e2) then begin
aux_solve (loc0, s2e1, s2e2) end else begin
trans3_env_hypo_add_prop (loc0, s2exp_bool false)
end
end
implement
s2exp_hypo_equal_solve (loc0, s2e1, s2e2) = let
val s2e1 = s2exp_whnf s2e1 and s2e2 = s2exp_whnf s2e2
in
case+ (s2e1.s2exp_node, s2e2.s2exp_node) of
| (_, _) when (s2exp_is_abscon s2e1 andalso s2exp_is_abscon s2e2) =>
s2exp_hypo_equal_solve_con (loc0, s2e1, s2e2)
| (S2Ecst s2c1, S2Ecst s2c2) when s2c1 = s2c2 => ()
| (S2Evar s2v1, S2Evar s2v2) => let
val sgn = compare_s2var_s2var (s2v1, s2v2)
in
case+ sgn of
| _ when sgn > 0 => begin
trans3_env_hypo_add_bind (loc0, s2v1, s2e2)
end
| _ when sgn < 0 => begin
trans3_env_hypo_add_bind (loc0, s2v2, s2e1)
end
| _ => ()
end | (S2Evar s2v1, _) => let
in
trans3_env_hypo_add_bind (loc0, s2v1, s2e2)
end | (_, S2Evar s2v2) => let
in
trans3_env_hypo_add_bind (loc0, s2v2, s2e1)
end | (S2Efun (_, _, _, _, s2es11, s2e12),
S2Efun (_, _, _, _, s2es21, s2e22)) => begin
s2explst_hypo_equal_solve (loc0, s2es21, s2es11);
s2exp_hypo_equal_solve (loc0, s2e12, s2e22)
end | (_, _) => trans3_env_hypo_add_eqeq (loc0, s2e1, s2e2)
end
implement
s2explst_hypo_equal_solve (loc0, s2es1, s2es2) =
case+ (s2es1, s2es2) of
| (cons (s2e1, s2es1), cons (s2e2, s2es2)) => begin
s2exp_hypo_equal_solve (loc0, s2e1, s2e2);
s2explst_hypo_equal_solve (loc0, s2es1, s2es2)
end | (nil (), nil ()) => ()
| (_, _) => begin
trans3_env_hypo_add_prop (loc0, s2exp_bool false)
end