blob: c00287753627dde7080e27fe9142344097923f64 [file] [log] [blame] [edit]
open Util.Source
open Ast
open Xl
(* Helpers *)
let eq_opt eq_x xo1 xo2 =
match xo1, xo2 with
| Some x1, Some x2 -> eq_x x1 x2
| _, _ -> xo1 = xo2
let eq_list eq_x xs1 xs2 =
List.length xs1 = List.length xs2 && List.for_all2 eq_x xs1 xs2
let eq_pair eq_x eq_y (x1, y1) (x2, y2) =
eq_x x1 x2 && eq_y y1 y2
(* Ids *)
let eq_id i1 i2 =
i1.it = i2.it
let eq_atom atom1 atom2 =
Atom.eq atom1 atom2
let eq_mixop op1 op2 =
Mixop.eq op1 op2
(* Iteration *)
let rec eq_iter iter1 iter2 =
match iter1, iter2 with
| ListN (e1, ido1), ListN (e2, ido2) -> eq_exp e1 e2 && eq_opt eq_id ido1 ido2
| _, _ -> iter1 = iter2
(* Types *)
and eq_typ t1 t2 =
match t1.it, t2.it with
| VarT (id1, as1), VarT (id2, as2) -> eq_id id1 id2 && eq_list eq_arg as1 as2
| TupT xts1, TupT xts2 -> eq_list (eq_pair eq_exp eq_typ) xts1 xts2
| IterT (t11, iter1), IterT (t21, iter2) ->
eq_typ t11 t21 && eq_iter iter1 iter2
| _, _ -> t1.it = t2.it
and eq_deftyp dt1 dt2 =
match dt1.it, dt2.it with
| AliasT t1, AliasT t2 -> eq_typ t1 t2
| StructT tfs1, StructT tfs2 -> eq_list eq_typfield tfs1 tfs2
| VariantT tcs1, VariantT tcs2 -> eq_list eq_typcase tcs1 tcs2
| _, _ -> false
and eq_typfield (atom1, (_binds1, t1, prems1), _) (atom2, (_binds2, t2, prems2), _) =
eq_atom atom1 atom2 && eq_typ t1 t2 && eq_list eq_prem prems1 prems2
and eq_typcase (op1, (_binds1, t1, prems1), _) (op2, (_binds2, t2, prems2), _) =
eq_mixop op1 op2 && eq_typ t1 t2 && eq_list eq_prem prems1 prems2
(* Expressions *)
and eq_exp e1 e2 =
match e1.it, e2.it with
| VarE id1, VarE id2 -> eq_id id1 id2
| UnE (op1, ot1, e11), UnE (op2, ot2, e21) ->
op1 = op2 && ot1 = ot2 && eq_exp e11 e21
| BinE (op1, ot1, e11, e12), BinE (op2, ot2, e21, e22) ->
op1 = op2 && ot1 = ot2 && eq_exp e11 e21 && eq_exp e12 e22
| CmpE (op1, ot1, e11, e12), CmpE (op2, ot2, e21, e22) ->
op1 = op2 && ot1 = ot2 && eq_exp e11 e21 && eq_exp e12 e22
| LiftE e11, LiftE e21
| LenE e11, LenE e21 -> eq_exp e11 e21
| IdxE (e11, e12), IdxE (e21, e22)
| CompE (e11, e12), CompE (e21, e22)
| MemE (e11, e12), MemE (e21, e22)
| CatE (e11, e12), CatE (e21, e22) -> eq_exp e11 e21 && eq_exp e12 e22
| SliceE (e11, e12, e13), SliceE (e21, e22, e23) ->
eq_exp e11 e21 && eq_exp e12 e22 && eq_exp e13 e23
| UpdE (e11, p1, e12), UpdE (e21, p2, e22)
| ExtE (e11, p1, e12), ExtE (e21, p2, e22) ->
eq_exp e11 e21 && eq_path p1 p2 && eq_exp e12 e22
| TupE es1, TupE es2
| ListE es1, ListE es2 -> eq_list eq_exp es1 es2
| StrE efs1, StrE efs2 -> eq_list eq_expfield efs1 efs2
| DotE (e11, atom1), DotE (e21, atom2) -> eq_exp e11 e21 && eq_atom atom1 atom2
| UncaseE (e1, op1), UncaseE (e2, op2) -> eq_mixop op1 op2 && eq_exp e1 e2
| CallE (id1, as1), CallE (id2, as2) -> eq_id id1 id2 && eq_list eq_arg as1 as2
| IterE (e11, iter1), IterE (e21, iter2) ->
eq_exp e11 e21 && eq_iterexp iter1 iter2
| OptE eo1, OptE eo2 -> eq_opt eq_exp eo1 eo2
| ProjE (e1, i1), ProjE (e2, i2) -> eq_exp e1 e2 && i1 = i2
| TheE e1, TheE e2 -> eq_exp e1 e2
| CaseE (op1, e1), CaseE (op2, e2) -> eq_mixop op1 op2 && eq_exp e1 e2
| CvtE (e1, nt11, nt12), CvtE (e2, nt21, nt22) ->
eq_exp e1 e2 && nt11 = nt21 && nt12 = nt22
| SubE (e1, t11, t12), SubE (e2, t21, t22) ->
eq_exp e1 e2 && eq_typ t11 t21 && eq_typ t12 t22
| _, _ -> e1.it = e2.it
and eq_expfield (atom1, e1) (atom2, e2) =
eq_atom atom1 atom2 && eq_exp e1 e2
and eq_path p1 p2 =
match p1.it, p2.it with
| RootP, RootP -> true
| IdxP (p11, e1), IdxP (p21, e2) -> eq_path p11 p21 && eq_exp e1 e2
| SliceP (p11, e11, e12), SliceP (p21, e21, e22) ->
eq_path p11 p21 && eq_exp e11 e21 && eq_exp e12 e22
| DotP (p11, atom1), DotP (p21, atom2) -> eq_path p11 p21 && eq_atom atom1 atom2
| _, _ -> p1.it = p2.it
and eq_iterexp (iter1, xes1) (iter2, xes2) =
eq_iter iter1 iter2 && eq_list (eq_pair eq_id eq_exp) xes1 xes2
(* Grammars *)
and eq_sym g1 g2 =
match g1.it, g2.it with
| VarG (id1, args1), VarG (id2, args2) ->
eq_id id1 id2 && eq_list eq_arg args1 args2
| SeqG gs1, SeqG gs2
| AltG gs1, AltG gs2 -> eq_list eq_sym gs1 gs2
| RangeG (g11, g12), RangeG (g21, g22) -> eq_sym g11 g21 && eq_sym g12 g22
| IterG (g11, iter1), IterG (g21, iter2) ->
eq_sym g11 g21 && eq_iterexp iter1 iter2
| AttrG (e1, g11), AttrG (e2, g21) -> eq_exp e1 e2 && eq_sym g11 g21
| _, _ -> g1.it = g2.it
(* Premises *)
and eq_prem prem1 prem2 =
match prem1.it, prem2.it with
| RulePr (id1, op1, e1), RulePr (id2, op2, e2) ->
eq_id id1 id2 && eq_mixop op1 op2 && eq_exp e1 e2
| IfPr e1, IfPr e2 -> eq_exp e1 e2
| IterPr (prem1, e1), IterPr (prem2, e2) ->
eq_prem prem1 prem2 && eq_iterexp e1 e2
| LetPr (e1, e1', ids1), LetPr (e2, e2', ids2) ->
eq_exp e1 e2 && eq_exp e1' e2' && ids1 = ids2
| _, _ -> prem1.it = prem2.it
(* Definitions *)
and eq_arg a1 a2 =
match a1.it, a2.it with
| ExpA e1, ExpA e2 -> eq_exp e1 e2
| TypA t1, TypA t2 -> eq_typ t1 t2
| DefA id1, DefA id2 -> eq_id id1 id2
| GramA g1, GramA g2 -> eq_sym g1 g2
| _, _ -> false