diff --git a/.github/workflows/ci-spectec.yml b/.github/workflows/ci-spectec.yml index 5568044f82..49ae1bb1e7 100644 --- a/.github/workflows/ci-spectec.yml +++ b/.github/workflows/ci-spectec.yml @@ -17,11 +17,23 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} - name: Setup OCaml uses: ocaml/setup-ocaml@v2 with: ocaml-compiler: 4.14.x + - name: Setup Haskell + uses: haskell/actions/setup@v2 + with: + ghc-version: 9.2 + - name: Setup Lean + run: | + cd /tmp + curl -LO https://github.com/leanprover/lean4-nightly/releases/download/nightly-2023-02-10/lean-4.0.0-nightly-2023-02-10-linux.tar.zst + tar xaf lean-4.0.0-nightly-2023-02-10-linux.tar.zst + echo "/tmp/lean-4.0.0-nightly-2023-02-10-linux/bin" >> $GITHUB_PATH - name: Setup Dune run: opam install --yes dune menhir mdx - name: Setup Latex diff --git a/spectec/.gitignore b/spectec/.gitignore index 96abbd1af7..850ddd0860 100644 --- a/spectec/.gitignore +++ b/spectec/.gitignore @@ -1 +1,9 @@ watsup +watsup-haskell +watsup-lean4 + +# lean stuff +build +lake-packages + +.direnv diff --git a/spectec/Makefile b/spectec/Makefile index 3ca2d6343f..702e37afd6 100644 --- a/spectec/Makefile +++ b/spectec/Makefile @@ -3,16 +3,18 @@ NAME = watsup EXT = $(NAME) -TESTDIRS = test-frontend test-latex +TESTDIRS = test-frontend test-middlend test-latex +DUNE_OPTS ?= + # Main targets .PHONY: default all ci -default: exe +default: exe exe-haskell all: exe latex test -ci: all test-frontend test-latex +ci: all test-frontend test-middlend test-latex # Executable @@ -24,9 +26,8 @@ OUTDIR = _build/default/src .PHONY: exe exe: - dune build $(SRCDIR)/$(EXE) - ln -f $(OUTDIR)/$(EXE) ./$(NAME) - + dune build $(DUNE_OPTS) $(SRCDIR)/$(EXE) + ln -sf $(OUTDIR)/$(EXE) ./$(NAME) # Latex diff --git a/spectec/lake-manifest.json b/spectec/lake-manifest.json new file mode 100644 index 0000000000..1e31dae761 --- /dev/null +++ b/spectec/lake-manifest.json @@ -0,0 +1 @@ +{"version": 4, "packagesDir": "lake-packages", "packages": []} diff --git a/spectec/lakefile.lean b/spectec/lakefile.lean new file mode 100644 index 0000000000..db0142a79b --- /dev/null +++ b/spectec/lakefile.lean @@ -0,0 +1,10 @@ +import Lake + +open Lake DSL + +package spectec + +@[default_target] +lean_lib SpecTec where + +/- require std from git "https://github.com/leanprover/std4" @ "main" -/ diff --git a/spectec/lean-toolchain b/spectec/lean-toolchain new file mode 100644 index 0000000000..5bf01da5f3 --- /dev/null +++ b/spectec/lean-toolchain @@ -0,0 +1 @@ +leanprover/lean4:nightly-2023-02-10 diff --git a/spectec/src/backend-haskell/dune b/spectec/src/backend-haskell/dune new file mode 100644 index 0000000000..be8ddf8467 --- /dev/null +++ b/spectec/src/backend-haskell/dune @@ -0,0 +1,5 @@ +(library + (name backend_haskell) + (libraries util el frontend str) + (modules gen) +) diff --git a/spectec/src/backend-haskell/gen.ml b/spectec/src/backend-haskell/gen.ml new file mode 100644 index 0000000000..b2565ee2d9 --- /dev/null +++ b/spectec/src/backend-haskell/gen.ml @@ -0,0 +1,157 @@ +open Il.Ast + +let include_input = false + +let parens s = "(" ^ s ^ ")" +let ($$) s1 s2 = parens (s1 ^ " " ^ s2) +let render_tuple how tys = parens (String.concat ", " (List.map how tys)) + +let render_type_name (id : id) = String.capitalize_ascii id.it + +let render_rec_con (id : id) = "Mk" ^ render_type_name id + +let is_reserved = function + | "data" + -> true + | _ -> false + +let make_id s = match s with + | s when is_reserved s -> s ^ "_" + | s -> String.map (function + | '.' -> '_' + | '-' -> '_' + | c -> c + ) s + +let render_con_name id : atom -> string = function + | Atom s -> + (* Lets disambiguate always, to start with + if String.starts_with ~prefix:"_" s + then render_type_name id ^ s + else String.capitalize_ascii s + *) + if String.starts_with ~prefix:"_" s + then render_type_name id ^ make_id s + else render_type_name id ^ "_" ^ make_id s + | a -> "{- render_con_name: TODO -} " ^ Il.Print.string_of_atom a + +let render_con_name' (typ : typ) a = match typ.it with + | VarT id -> render_con_name id a + | _ -> "_ {- render_con_name': Typ not id " ^ Il.Print.string_of_typ typ ^ " -}" + +let render_field_name : atom -> string = function + | Atom s -> String.uncapitalize_ascii (make_id s) + | a -> "{- render_field_name: TODO -} " ^ Il.Print.string_of_atom a + + +let rec render_typ (ty : typ) = match ty.it with + | VarT id -> render_type_name id + | BoolT -> "Bool" + | NatT -> "Natural" + | TextT -> "String" + | TupT tys -> render_tuple render_typ tys + | IterT (ty, Opt) -> "Maybe" $$ render_typ ty + | IterT (ty, _) -> "[" ^ render_typ ty ^ "]" + +let _unsupported_def d = + "{- " ^ + Il.Print.string_of_def d ^ + "\n-}" + +let rec prepend first rest = function + | [] -> "" + | (x::xs) -> first ^ x ^ prepend rest rest xs + + +let render_variant_inj id1 id2 = + render_type_name id1 ^ "_of_" ^ render_type_name id2 + +let render_variant_inj' (typ1 : typ) (typ2 : typ) = match typ1.it, typ2.it with + | VarT id1, VarT id2 -> render_variant_inj id1 id2 + | _, _ -> "_ {- render_variant_inj': Typs not ids -}" + +let render_variant_case id (case : typcase) = match case with + | (a, {it = TupT [];_}, _hints) -> render_con_name id a + | (a, ty, _hints) -> render_con_name id a ^ " " ^ render_typ ty + +let rec render_exp (exp : exp) = match exp.it with + | VarE v -> v.it + | BoolE true -> "True" + | BoolE false -> "Frue" + | NatE n -> string_of_int n + | TextE t -> "\"" ^ String.escaped t ^ "\"" + | MixE (_, e) -> render_exp e + | TupE es -> render_tuple render_exp es + | IterE (e, _) -> render_exp e + | CaseE (a, e) -> render_case a e exp.note + | SubE (e, typ1, typ2) -> render_variant_inj' typ2 typ1 $$ render_exp e + | DotE (e, a) -> render_exp e ^ "." ^ render_field_name a + | IdxE (e1, e2) -> parens (render_exp e1 ^ " !! " ^ ("fromIntegral" $$ render_exp e2)) + | BinE (AddOp, e1, e2) -> parens (render_exp e1 ^ " + " ^ render_exp e2) + | _ -> "undefined {- " ^ Il.Print.string_of_exp exp ^ " -}" + +and render_case a e typ = + if e.it = TupE [] + then render_con_name' typ a + else render_con_name' typ a $$ render_exp e + +let render_clause (id : id) (clause : clause) = match clause.it with + | DefD (_binds, lhs, rhs, premise) -> + (if premise <> [] then "-- Premises ignored! \n" else "") ^ + make_id id.it ^ " " ^ render_exp lhs ^ " = " ^ render_exp rhs + +let rec render_def (d : def) = + begin + if include_input then + "{- " (* ^ Util.Source.string_of_region d.at ^ "\n"*) ^ + Il.Print.string_of_def d ^ + "\n-}\n" + else "" + end ^ + match d.it with + | SynD (id, deftyp) -> + begin match deftyp.it with + | AliasT ty -> + "type " ^ render_type_name id ^ " = " ^ render_typ ty + | NotationT (mop, ty) -> + "type " ^ render_type_name id ^ " = {- mixop: " ^ Il.Print.string_of_mixop mop ^ " -} " ^ render_typ ty + | VariantT cases -> + "data " ^ render_type_name id ^ prepend "\n = " "\n | " ( + List.map (render_variant_case id) cases + ) + | StructT fields -> + (* + "type " ^ render_type_name id ^ " = " ^ render_tuple render_typ ( + List.map (fun (_a, ty, _hints) -> ty) fields + ) + *) + "data " ^ render_type_name id ^ " = " ^ render_rec_con id ^ prepend "\n { " "\n , " ( + List.map (fun (a, ty, _hints) -> render_field_name a ^ " :: " ^ render_typ ty) fields + ) ^ "\n }" + end + | DecD (id, typ1, typ2, clauses) -> + make_id id.it ^ " :: " ^ render_typ typ1 ^ " -> " ^ render_typ typ2 ^ "\n" ^ + if clauses = [] + then make_id id.it ^ " = error \"function without clauses\"" + else String.concat "\n" (List.map (render_clause id) clauses) + | RecD defs -> + String.concat "\n" (List.map render_def defs) + | _ -> "" + +let render_script (el : script) = + String.concat "\n\n" (List.map render_def el) + +let gen_string (el : script) = + "{-# LANGUAGE OverloadedRecordDot #-}\n" ^ + "{-# LANGUAGE DuplicateRecordFields #-}\n" ^ + "module Test where\n" ^ + "import Prelude (Bool, String, undefined, error, Maybe, fromIntegral, (+), (!!))\n" ^ + "import Numeric.Natural (Natural)\n" ^ + render_script el + + +let gen_file file el = + let haskell_code = gen_string el in + let oc = Out_channel.open_text file in + Fun.protect (fun () -> Out_channel.output_string oc haskell_code) + ~finally:(fun () -> Out_channel.close oc) diff --git a/spectec/src/backend-haskell/gen.mli b/spectec/src/backend-haskell/gen.mli new file mode 100644 index 0000000000..5df21766f4 --- /dev/null +++ b/spectec/src/backend-haskell/gen.mli @@ -0,0 +1,2 @@ +val gen_string : Il.Ast.script -> string +val gen_file : string -> Il.Ast.script -> unit diff --git a/spectec/src/backend-lean4/dune b/spectec/src/backend-lean4/dune new file mode 100644 index 0000000000..ea28fde790 --- /dev/null +++ b/spectec/src/backend-lean4/dune @@ -0,0 +1,5 @@ +(library + (name backend_lean4) + (libraries util el frontend str) + (modules gen) +) diff --git a/spectec/src/backend-lean4/gen.ml b/spectec/src/backend-lean4/gen.ml new file mode 100644 index 0000000000..f0fc51566c --- /dev/null +++ b/spectec/src/backend-lean4/gen.ml @@ -0,0 +1,319 @@ +open Il.Ast + +let error at msg = Util.Source.error at "Lean4 generation" msg + +let include_input = false + +let parens s = "(" ^ s ^ ")" +let brackets s = "[" ^ s ^ "]" +let braces s = "{" ^ s ^ "}" +let ($$$) s1 ss = parens (String.concat " " (s1 :: ss)) +let ($$) s1 s2 = s1 $$$ [s2] +let render_tuple how tys = parens (String.concat ", " (List.map how tys)) +let render_list how tys = brackets (String.concat ", " (List.map how tys)) + +(* let render_rec_con (id : id) = "Mk" ^ render_type_name id *) + +let is_reserved = function + | "in" + | "export" + | "import" + | "global" + | "local" + | "mut" + -> true + | _ + -> false + +let make_id s = match s with + | s when is_reserved s -> "«" ^ s ^ "»" + | s -> String.map (function + | '.' -> '_' + | '-' -> '_' + | c -> c + ) s + + +let render_id (id : id) = make_id id.it + +let render_fun_id (id : id) = "«$" ^ id.it ^ "»" + +let render_type_name (id : id) = make_id (String.capitalize_ascii id.it) + +let render_rule_name _qual _ty_id (rule_id : id) (i : int) : string = + if rule_id.it = "" + then "rule_" ^ string_of_int i + else make_id rule_id.it + +let render_con_name qual id : atom -> string = function + | Atom s -> + (if qual then render_type_name id ^ "." else "") ^ + make_id s + | a -> "/- render_con_name: TODO -/ " ^ Il.Print.string_of_atom a + +let render_con_name' qual (typ : typ) a = match typ.it with + | VarT id -> render_con_name qual id a + | _ -> "_ {- render_con_name': Typ not id " ^ Il.Print.string_of_typ typ ^ " -}" + +let render_field_name : atom -> string = function + | Atom s -> make_id s + | a -> "/- render_field_name: TODO -/ " ^ Il.Print.string_of_atom a + + +let wrap_type_iter (ty : string) : iter -> string = function + | Opt -> "Option" $$ ty + | _ -> "List" $$ ty + +let wrap_type_iters (ty : string) : iter list -> string = List.fold_left wrap_type_iter ty + +let rec render_typ (ty : typ) = match ty.it with + | VarT id -> render_type_name id + | BoolT -> "Bool" + | NatT -> "Nat" + | TextT -> "String" + | TupT [] -> "Unit" + | TupT tys -> render_tuple_typ tys + | IterT (ty, it) -> wrap_type_iter (render_typ ty) it + +and render_tuple_typ tys = parens (String.concat " × " (List.map render_typ tys)) + +let render_variant_case id ((a, ty, _hints) : typcase) = + render_con_name false id a ^ " : " ^ + if ty.it = TupT [] + then render_type_name id + else render_typ ty ^ " -> " ^ render_type_name id + +let rec render_exp (exp : exp) = match exp.it with + | VarE v -> render_id v + | BoolE true -> "True" + | BoolE false -> "Frue" + | NatE n -> string_of_int n + | TextE t -> "\"" ^ String.escaped t ^ "\"" + | MixE (_, e) -> render_exp e + | TupE es -> render_tuple render_exp es + | ListE es -> render_list render_exp es + | OptE None -> "none" + | OptE (Some e) -> "some" $$ render_exp e + | TheE e -> render_exp e ^ ".get!" + | IterE (e, (iter, vs)) -> begin match e.it with + (* Short-ciruit v*; use variable directly instead of calling map *) + | VarE v when [v.it] = List.map (fun (v : id) -> v.it) vs -> render_id v + | _ -> match iter, vs with + | (List|List1|ListN _), [] -> + "[" ^ render_exp e ^ "]" + | (List|List1|ListN _), [v] -> + "List.map" $$$ [render_lam v e; render_id v] + | (List|List1|ListN _), [v1; v2] -> + "List.zipWith" $$$ [ "(λ " ^ render_id v1 ^ " " ^ render_id v2 ^ " ↦ " ^ render_exp e ^ ")"; render_id v1; render_id v2 ] + | Opt, [] -> "some" $$ render_exp e + | Opt, [v] -> + "Option.map" $$$ [render_lam v e; render_id v] + | Opt, [v1; v2] -> + "Option.zipWith" $$$ [ "(λ " ^ render_id v1 ^ " " ^ render_id v2 ^ " ↦ " ^ render_exp e ^ ")"; render_id v1; render_id v2 ] + | _, _ -> + render_exp e ^ " /- " ^ Il.Print.string_of_iterexp (iter, vs) ^ " -/" + end + | CaseE (a, e) -> render_case a e exp.note + | StrE fields -> braces ( String.concat ", " (List.map (fun (a, e) -> + render_field_name a ^ " := " ^ render_exp e + ) fields)) + | SubE _ -> error exp.at "SubE encountered. Did the SubE elimination pass run?" + | DotE (e, a) -> render_dot (render_exp e) a + | UpdE (exp1, path, exp2) -> + render_path path (render_exp exp1) (fun _ -> render_exp exp2) + | ExtE (exp1, path, exp2) -> + render_path path (render_exp exp1) (fun old_val -> "List.append" $$$ [old_val; render_exp exp2]) + | IdxE (e1, e2) -> render_idx (render_exp e1) e2 + | SliceE (e1, e2, e3) -> render_slice (render_exp e1) e2 e3 + | LenE e -> render_exp e ^ ".length" + | CallE (id, e) -> render_fun_id id $$ render_exp e + | UnE (MinusOp, e1) -> parens ("0 - " ^ render_exp e1) + | BinE (AddOp, e1, e2) -> parens (render_exp e1 ^ " + " ^ render_exp e2) + | BinE (SubOp, e1, e2) -> parens (render_exp e1 ^ " - " ^ render_exp e2) + | BinE (MulOp, e1, e2) -> parens (render_exp e1 ^ " * " ^ render_exp e2) + | BinE (ExpOp, e1, e2) -> parens ("Nat.pow" $$ render_exp e1 $$ render_exp e2) + | BinE (DivOp, e1, e2) -> parens ("Nat.div" $$ render_exp e1 $$ render_exp e2) + | BinE (AndOp, e1, e2) -> parens (render_exp e1 ^ " && " ^ render_exp e2) + | BinE (EquivOp, e1, e2) -> parens (render_exp e1 ^ " = " ^ render_exp e2) + | BinE (OrOp, e1, e2) -> parens (render_exp e1 ^ " || " ^ render_exp e2) + | CmpE (EqOp, e1, e2) -> parens (render_exp e1 ^ " == " ^ render_exp e2) + | CmpE (NeOp, e1, e2) -> parens (render_exp e1 ^ " != " ^ render_exp e2) + | CmpE (LeOp, e1, e2) -> parens (render_exp e1 ^ " <= " ^ render_exp e2) + | CmpE (LtOp, e1, e2) -> parens (render_exp e1 ^ " < " ^ render_exp e2) + | CmpE (GeOp, e1, e2) -> parens (render_exp e1 ^ " >= " ^ render_exp e2) + | CmpE (GtOp, e1, e2) -> parens (render_exp e1 ^ " > " ^ render_exp e2) + | CatE (e1, e2) -> parens (render_exp e1 ^ " ++ " ^ render_exp e2) + | CompE (e1, e2) -> parens (render_exp e2 ^ " ++ " ^ render_exp e1) (* NB! flip order *) + | _ -> "default /- " ^ Il.Print.string_of_exp exp ^ " -/" + +and render_dot e_string a = e_string ^ "." ^ render_field_name a + +and render_idx e_string exp = parens (e_string ^ ".get! " ^ render_exp exp) + +and render_slice e_string e1 e2 = parens (e_string ^ ".slice " ^ render_exp e1 ^ " " ^ render_exp e2) + +(* The path is inside out, in a way, hence the continuation passing style here *) +and render_path (path : path) old_val (k : string -> string) : string = match path.it with + | RootP -> k old_val + | DotP (path', a) -> + render_path path' old_val (fun old_val -> + "{" ^ old_val ^ " with " ^ render_field_name a ^ " := " ^ k (render_dot old_val a) ^ " }" + ) + | SliceP (path', idx1_exp, idx2_exp) -> + render_path path' old_val (fun old_val -> + "(" ^ old_val ^ ".upds " ^ render_exp idx1_exp ^ " " ^ render_exp idx2_exp ^ " " ^ k (render_slice old_val idx1_exp idx2_exp) ^ ")" + ) + | IdxP (path', idx_exp) -> + render_path path' old_val (fun old_val -> + "(" ^ old_val ^ ".upd " ^ render_exp idx_exp ^ " " ^ k (render_idx old_val idx_exp) ^ ")" + ) + + +and render_case a e typ = + if e.it = TupE [] + then render_con_name' true typ a + else render_con_name' true typ a $$ render_exp e + +and render_lam v e = match e.it with + | CallE (f, {it = VarE v2;_}) when v.it = v2.it -> render_fun_id f + | _ -> "(λ " ^ render_id v ^ " ↦ " ^ render_exp e ^ ")" + +let render_clause (_id : id) (clause : clause) = match clause.it with + | DefD (_binds, lhs, rhs, premise) -> + (if premise <> [] then "-- Premises ignored! \n" else "") ^ + "\n | " ^ render_exp lhs ^ " => " ^ render_exp rhs + +let show_input (d:def) = + if include_input then + "/- " (* ^ Util.Source.string_of_region d.at ^ "\n"*) ^ + Il.Print.string_of_def d ^ + "\n-/\n" + else "" + +let rec render_prem (prem : premise) = + match prem.it with + | RulePr (pid, _mixops, pexp) -> render_type_name pid $$ render_exp pexp + | IfPr (pexp) -> render_exp pexp + | IterPr (prem, iterexp) -> + begin match iterexp with + | (List|List1|ListN _), [v] -> + "(Forall (λ " ^ render_id v ^ " ↦ " ^ render_prem prem ^ ") " ^ render_id v ^ ")" + | (List|List1|ListN _), [v1; v2] -> + "(Forall₂ (λ " ^ render_id v1 ^ " " ^ render_id v2 ^ " ↦ " ^ render_prem prem ^ ") " ^ render_id v1 ^ " " ^ render_id v2 ^ ")" + | Opt, [v] -> + "(Forall (λ " ^ render_id v ^ " ↦ " ^ render_prem prem ^ ") " ^ render_id v ^ ".toList)" + | Opt, [v1; v2] -> + "(Forall₂ (λ " ^ render_id v1 ^ " " ^ render_id v2 ^ " ↦ " ^ render_prem prem ^ ") " ^ render_id v1 ^ ".toList " ^ render_id v2 ^ ".toList)" + | _,_ -> render_prem prem ^ " /- " ^ Il.Print.string_of_iterexp iterexp ^ " -/" + end + | ElsePr -> error prem.at "ElsePr encountered. Did the SubE elimination pass run?" + | NegPr prem -> "Not" $$ render_prem prem + | LetPr _ -> error prem.at "LetPr not supported" + +let rec render_def (d : def) = + match d.it with + | SynD (id, deftyp) -> + show_input d ^ + begin match deftyp.it with + | AliasT ty -> + "@[reducible] def " ^ render_type_name id ^ " := " ^ render_typ ty + | NotationT (mop, ty) -> + "@[reducible] def " ^ render_type_name id ^ " := /- mixop: " ^ Il.Print.string_of_mixop mop ^ " -/ " ^ render_typ ty + | VariantT cases -> + "inductive " ^ render_type_name id ^ " where" ^ String.concat "" ( + List.map (fun case -> "\n | " ^ render_variant_case id case) cases + ) ^ + (if cases = [] then "\n deriving BEq" else "\n deriving Inhabited, BEq") + | StructT fields -> + "structure " ^ render_type_name id ^ " where " ^ + String.concat "" ( List.map (fun (a, ty, _hints) -> + "\n " ^ render_field_name a ^ " : " ^ render_typ ty + ) fields) ^ + "\n deriving Inhabited, BEq\n" ^ + (* Generate an instance so that ++ works, for CompE *) + "instance : Append " ^ render_type_name id ^ " where\n" ^ + " append := fun r1 r2 => {\n" ^ + String.concat "" (List.map (fun (a, _ty, _hints) -> + " " ^ render_field_name a ^ " := r1." ^ render_field_name a ^ " ++ r2." ^ render_field_name a ^ ",\n" + ) fields) ^ + " }" + end + | DecD (id, typ1, typ2, clauses) -> + show_input d ^ + "def " ^ render_fun_id id ^ " : " ^ render_typ typ1 ^ " -> " ^ render_typ typ2 ^ + begin if clauses = [] then " := default" else + String.concat "" (List.map (render_clause id) clauses) + end + + | RelD (id, _mixop, typ, rules) -> + show_input d ^ + "inductive " ^ render_type_name id ^ " : " ^ render_typ typ ^ " -> Prop where" ^ + String.concat "" (List.mapi (fun i (rule : rule) -> match rule.it with + | RuleD (rule_id, binds, _mixop, exp, prems) -> + "\n | " ^ render_rule_name false id rule_id i ^ " " ^ + String.concat " " (List.map (fun ((bid : id), btyp, iters) -> + parens (render_id bid ^ " : " ^ wrap_type_iters (render_typ btyp) iters) + ) binds) ^ " : " ^ + String.concat "" (List.map (fun (prem : premise) -> + "\n " ^ render_prem prem ^ " -> " + ) prems) ^ + "\n " ^ (render_type_name id $$ render_exp exp) + ) rules) + + | RecD [def] -> + (* Self-recursion is always fine *) + render_def def + + | RecD defs -> + "mutual\n" ^ + String.concat "\n" (List.map render_def defs) ^ + "end" + + | HintD _ -> "" + +let render_script (el : script) = + String.concat "\n\n" (List.map render_def el) + +let gen_string (el : script) = + "/- Lean 4 export -/\n" ^ + "\n" ^ + "/- A little prelude -/\n" ^ + "\n" ^ + "set_option linter.unusedVariables false\n" ^ + "\n" ^ + "instance : Append (Option a) where\n" ^ + " append := fun o1 o2 => match o1 with | none => o2 | _ => o1\n\n" ^ + "\n" ^ + "inductive Forall (R : α → Prop) : List α → Prop\n" ^ + " | nil : Forall R []\n" ^ + " | cons {a l₁} : R a → Forall R l₁ → Forall R (a :: l₁)\n" ^ + "attribute [simp] Forall.nil\n" ^ + "inductive Forall₂ (R : α → β → Prop) : List α → List β → Prop\n" ^ + " | nil : Forall₂ R [] []\n" ^ + " | cons {a b l₁ l₂} : R a b → Forall₂ R l₁ l₂ → Forall₂ R (a :: l₁) (b :: l₂)\n" ^ + "attribute [simp] Forall₂.nil\n" ^ + "def Option.zipWith : (α → β → γ) → Option α → Option β → Option γ\n" ^ + " | f, (some x), (some y) => some (f x y)\n" ^ + " | _, _, _ => none\n" ^ + "def Option.toList : Option α → List α\n" ^ + " | none => List.nil\n" ^ + " | some x => [x]\n" ^ + "def List.upd : List α → Nat → α → List α\n" ^ + " | [], _, _ => []\n" ^ + " | x::xs, 0, y => y :: xs\n" ^ + " | x::xs, n+1, y => x :: xs.upd n y\n" ^ + "def List.upds : List α → Nat → Nat → List α → List α\n" ^ + " | xs, n, m, ys => xs.take n ++ ys ++ xs.drop (n + m)\n" ^ + "def List.slice : List α → Nat → Nat → List α\n" ^ + " | xs, n, m => (xs.drop n)\n" ^ + "\n\n" ^ + "/- Now, the generated code -/\n" ^ + "\n" ^ + render_script el + + +let gen_file file el = + let haskell_code = gen_string el in + let oc = Out_channel.open_text file in + Fun.protect (fun () -> Out_channel.output_string oc haskell_code) + ~finally:(fun () -> Out_channel.close oc) diff --git a/spectec/src/backend-lean4/gen.mli b/spectec/src/backend-lean4/gen.mli new file mode 100644 index 0000000000..5df21766f4 --- /dev/null +++ b/spectec/src/backend-lean4/gen.mli @@ -0,0 +1,2 @@ +val gen_string : Il.Ast.script -> string +val gen_file : string -> Il.Ast.script -> unit diff --git a/spectec/src/dune b/spectec/src/dune index ea13545166..34ad7118af 100644 --- a/spectec/src/dune +++ b/spectec/src/dune @@ -9,5 +9,7 @@ (re_export middlend) (re_export backend_latex) (re_export backend_prose) + (re_export backend_haskell) + (re_export backend_lean4) ) ) diff --git a/spectec/src/exe-watsup/main.ml b/spectec/src/exe-watsup/main.ml index 98eb0a30d5..710f31b791 100644 --- a/spectec/src/exe-watsup/main.ml +++ b/spectec/src/exe-watsup/main.ml @@ -13,6 +13,8 @@ type target = | Check | Latex of Backend_latex.Config.config | Prose + | Haskell + | Lean4 let target = ref (Latex Backend_latex.Config.latex) @@ -22,6 +24,7 @@ type pass = | Unthe | Wild | Sideconditions + | Else | Animate (* This list declares the intended order of passes. @@ -30,7 +33,10 @@ Because passes have dependencies, and because some flags enable multiple passers (--all-passes, some targets), we do _not_ want to use the order of flags on the command line. *) -let all_passes = [ Sub; Totalize; Unthe; Wild; Sideconditions; Animate ] +let all_passes = [ Sub; Totalize; Unthe; Wild; Sideconditions; Else; Animate ] +(* Some backeneds require certain passes *) +let haskell_passes = [ Sub ] +let lean4_passes = [ Sub; Totalize; Unthe; Wild; Sideconditions; Else] let log = ref false (* log execution steps *) let dst = ref false (* patch files *) @@ -48,6 +54,7 @@ let print_all_il = ref false module PS = Set.Make(struct type t = pass let compare = compare; end) let selected_passes = ref (PS.empty) let enable_pass pass = selected_passes := PS.add pass !selected_passes +let enable_passes = List.iter enable_pass (* Il pass metadata *) @@ -57,6 +64,7 @@ let pass_flag = function | Unthe -> "the-elimination" | Wild -> "wildcards" | Sideconditions -> "sideconditions" + | Else -> "else-elimination" | Animate -> "animate" let pass_desc = function @@ -65,6 +73,7 @@ let pass_desc = function | Unthe -> "Eliminate the ! operator in relations" | Wild -> "Eliminate wildcards and equivalent expressions" | Sideconditions -> "Infer side conditions" + | Else -> "Eliminate otherwise/else" | Animate -> "Animate equality conditions" let run_pass : pass -> Il.Ast.script -> Il.Ast.script = function @@ -73,6 +82,7 @@ let run_pass : pass -> Il.Ast.script -> Il.Ast.script = function | Unthe -> Middlend.Unthe.transform | Wild -> Middlend.Wild.transform | Sideconditions -> Middlend.Sideconditions.transform + | Else -> Middlend.Else.transform | Animate -> Middlend.Animate.transform (* Argument parsing *) @@ -103,12 +113,15 @@ let argspec = Arg.align "--sphinx", Arg.Unit (fun () -> target := Latex Backend_latex.Config.sphinx), " Generate Latex for Sphinx"; "--prose", Arg.Unit (fun () -> target := Prose), " Generate prose"; + "--haskell", Arg.Unit (fun () -> target := Haskell; enable_passes haskell_passes ), " Produce Haskell code"; + "--lean4", Arg.Unit (fun () -> target := Lean4; enable_passes lean4_passes), " Produce Lean4 code"; + "--print-il", Arg.Set print_elab_il, " Print il (after elaboration)"; "--print-final-il", Arg.Set print_final_il, " Print final il"; "--print-all-il", Arg.Set print_all_il, " Print il after each step"; ] @ List.map pass_argspec all_passes @ [ - "--all-passes", Arg.Unit (fun () -> List.iter enable_pass all_passes)," Run all passes"; + "--all-passes", Arg.Unit (fun () -> enable_passes all_passes)," Run all passes"; "-help", Arg.Unit ignore, ""; "--help", Arg.Unit ignore, ""; @@ -171,6 +184,16 @@ let () = let prose = Backend_prose.Translate.translate el in print_endline prose ) + | Haskell -> + if !odst = "" && !dsts = [] then + print_endline (Backend_haskell.Gen.gen_string il); + if !odst <> "" then + Backend_haskell.Gen.gen_file !odst il; + | Lean4 -> + if !odst = "" && !dsts = [] then + print_endline (Backend_haskell.Gen.gen_string il); + if !odst <> "" then + Backend_lean4.Gen.gen_file !odst il; ); log "Complete." with diff --git a/spectec/src/frontend/multiplicity.ml b/spectec/src/frontend/multiplicity.ml index 175b58c9ad..2b302aac17 100644 --- a/spectec/src/frontend/multiplicity.ml +++ b/spectec/src/frontend/multiplicity.ml @@ -306,6 +306,9 @@ and annot_prem env prem : Il.Ast.premise * occur = let prem1', occur1 = annot_prem env prem1 in let iter', occur' = annot_iterexp env occur1 iter prem.at in IterPr (prem1', iter'), occur' + | NegPr prem1 -> + let prem1', occur = annot_prem env prem1 in + NegPr prem1', occur in {prem with it}, occur let annot_exp env e = diff --git a/spectec/src/il/apart.ml b/spectec/src/il/apart.ml new file mode 100644 index 0000000000..9d36d44798 --- /dev/null +++ b/spectec/src/il/apart.ml @@ -0,0 +1,62 @@ +(* +This module implements a (consservative) apartness check: Given two (open) +expression (typically reduction rules LHSs), are they definitely apart. +*) + +open Util.Source +open Ast + +(* Looks at an expression of type list from the back and chops off all + known _elements_, followed by the list of all list expressions. + Returns it all in reverse order. + *) +let rec to_snoc_list (e : exp) : exp list * exp list = match e.it with + | ListE es -> List.rev es, [] + | CatE (e1, e2) -> + let tailelems2, listelems2 = to_snoc_list e2 in + if listelems2 = [] + (* Second list is fully known? Can look at first list *) + then let tailelems1, listelems1 = to_snoc_list e1 in + tailelems2 @ tailelems1, listelems1 + (* Second list has unknown elements, have to stop there *) + else tailelems2, listelems2 @ [e1] + | _ -> [], [e] + +(* We assume the expressions to be of the same type; for ill-typed inputs + no guarantees are made. *) +let rec apart (e1 : exp) (e2: exp) : bool = + if Eq.eq_exp e1 e2 then false else + (* + (fun b -> if not b then Printf.eprintf "apart\n %s\n %s\n %b\n" (Print.string_of_exp e1) (Print.string_of_exp e2) b; b) + *) + (match e1.it, e2.it with + (* A literal is never a literal of other type *) + | NatE n1, NatE n2 -> not (n1 = n2) + | BoolE b1, BoolE b2 -> not (b1 = b2) + | TextE t1, TextE t2 -> not (t1 = t2) + | CaseE (a1, exp1), CaseE (a2, exp2) -> + not (a1 = a2) || apart exp1 exp2 + | TupE es1, TupE es2 when List.length es1 = List.length es2 -> + List.exists2 apart es1 es2 + | (CatE _ | ListE _), (CatE _ | ListE _) -> + list_exp_apart e1 e2 + | SubE (e1, _, _), SubE (e2, _, _) -> apart e1 e2 + | MixE (mixop1, e1), MixE (mixop2, e2) -> + not (mixop1 = mixop2) || apart e1 e2 + (* We do not know anything about variables and functions *) + | _ , _ -> false (* conservative *) + ) + +(* Two list expressions are apart if either their manifest tail elements are apart *) +and list_exp_apart e1 e2 = snoc_list_apart (to_snoc_list e1) (to_snoc_list e2) + +and snoc_list_apart (tailelems1, listelems1) (tailelems2, listelems2) = + match tailelems1, listelems1, tailelems2, listelems2 with + (* If the heads are apart, the lists are apart *) + | e1 :: e1s, _, e2 :: e2s, _ -> apart e1 e2 || snoc_list_apart (e1s, listelems1) (e2s, listelems2) + (* If one list is definitely empty and the other list definitely isn't *) + | [], [], _ :: _, _ -> false + | _ :: _, _, [], [] -> false + (* Else, can't tell *) + | _, _, _, _ -> false + diff --git a/spectec/src/il/apart.mli b/spectec/src/il/apart.mli new file mode 100644 index 0000000000..174ce96d7e --- /dev/null +++ b/spectec/src/il/apart.mli @@ -0,0 +1,2 @@ +open Ast +val apart : exp -> exp -> bool diff --git a/spectec/src/il/ast.ml b/spectec/src/il/ast.ml index 18cafd638e..540a4b51b3 100644 --- a/spectec/src/il/ast.ml +++ b/spectec/src/il/ast.ml @@ -159,6 +159,7 @@ and premise' = | LetPr of exp * exp (* assignment *) | ElsePr (* otherwise *) | IterPr of premise * iterexp (* iteration *) + | NegPr of premise (* negation of a premise *) and hintdef = hintdef' phrase and hintdef' = diff --git a/spectec/src/il/dune b/spectec/src/il/dune index 38b4366dee..cf0169cfed 100644 --- a/spectec/src/il/dune +++ b/spectec/src/il/dune @@ -1,5 +1,5 @@ (library (name il) (libraries util) - (modules ast eq free print validation) + (modules ast eq free print validation apart) ) diff --git a/spectec/src/il/eq.ml b/spectec/src/il/eq.ml index 61fb22f964..6241a500e3 100644 --- a/spectec/src/il/eq.ml +++ b/spectec/src/il/eq.ml @@ -105,4 +105,5 @@ let rec eq_prem prem1 prem2 = | ElsePr, ElsePr -> true | IterPr (prem1, e1), IterPr (prem2, e2) -> eq_prem prem1 prem2 && eq_iterexp e1 e2 + | NegPr prem1, NegPr prem2 -> eq_prem prem1 prem2 | _, _ -> false diff --git a/spectec/src/il/free.ml b/spectec/src/il/free.ml index 43bcd12d49..fa1ff7a155 100644 --- a/spectec/src/il/free.ml +++ b/spectec/src/il/free.ml @@ -128,6 +128,7 @@ let rec free_prem prem = | LetPr (e1, e2) -> union (free_exp e1) (free_exp e2) | ElsePr -> empty | IterPr (prem', iter) -> union (free_prem prem') (free_iterexp iter) + | NegPr prem' -> free_prem prem' let free_rule rule = match rule.it with diff --git a/spectec/src/il/print.ml b/spectec/src/il/print.ml index e33beff47a..932b0eb0bd 100644 --- a/spectec/src/il/print.ml +++ b/spectec/src/il/print.ml @@ -204,6 +204,7 @@ let rec string_of_prem prem = string_of_prem prem' ^ string_of_iterexp iter | IterPr (prem', iter) -> "(" ^ string_of_prem prem' ^ ")" ^ string_of_iterexp iter + | NegPr prem' -> "unless " ^ string_of_prem prem' let region_comment indent at = if at = no_region then "" else diff --git a/spectec/src/il/print.mli b/spectec/src/il/print.mli index d86b0a75ee..12dc713294 100644 --- a/spectec/src/il/print.mli +++ b/spectec/src/il/print.mli @@ -6,6 +6,7 @@ val string_of_binop : binop -> string val string_of_cmpop : cmpop -> string val string_of_mixop : mixop -> string val string_of_iter : iter -> string +val string_of_iterexp : iterexp -> string val string_of_typ : typ -> string val string_of_exp : exp -> string val string_of_prem : premise -> string diff --git a/spectec/src/il/validation.ml b/spectec/src/il/validation.ml index 7703a0f951..fccb0b4784 100644 --- a/spectec/src/il/validation.ml +++ b/spectec/src/il/validation.ml @@ -506,6 +506,8 @@ let rec valid_prem env prem = | IterPr (prem', iter) -> let env' = valid_iterexp env iter in valid_prem env' prem' + | NegPr prem' -> + valid_prem env prem' let valid_rule env mixop t rule = diff --git a/spectec/src/middlend/dune b/spectec/src/middlend/dune index b07e76304c..bcfde71faa 100644 --- a/spectec/src/middlend/dune +++ b/spectec/src/middlend/dune @@ -7,6 +7,7 @@ wild unthe sideconditions + else animate ) ) diff --git a/spectec/src/middlend/else.ml b/spectec/src/middlend/else.ml new file mode 100644 index 0000000000..e2928c2bfd --- /dev/null +++ b/spectec/src/middlend/else.ml @@ -0,0 +1,79 @@ +(* +This transformation removes uses of the `otherwise` (`ElsePr`) premise from +inductive relations. + +It only supports binary relations. + +1. It figures out which rules are meant by “otherwise”: + + * All previous rules + * Excluding those that definitely can’t apply when the present rule applies + (decided by a simple and conservative comparision of the LHS). + +2. It creates an auxillary inductive unary predicate with these rules (LHS only). + +3. It replaces the `ElsePr` with the negation of that rule. + +*) + +open Util +open Source +open Il.Ast + +(* Errors *) + +let error at msg = Source.error at "else removal" msg + +let unary_mixfix : mixop = [[Atom ""]; [Atom ""]] + +let is_else prem = prem.it = ElsePr + +let replace_else aux_name lhs prem = match prem.it with + | ElsePr -> NegPr (RulePr (aux_name, unary_mixfix, lhs) $ prem.at) $ prem.at + | _ -> prem + +let unarize rule = match rule.it with + | RuleD (rid, binds, _mixop, exp, prems) -> + let lhs = match exp.it with + | TupE [lhs; _] -> lhs + | _ -> error exp.at "expected manifest pair" + in + { rule with it = RuleD (rid, binds, unary_mixfix, lhs, prems) } + +let not_apart lhs rule = match rule.it with + | RuleD (_, _, _, lhs2, _) -> not (Il.Apart.apart lhs lhs2) + +let rec go at id mixop typ typ1 prev_rules : rule list -> def list = function + | [] -> [ RelD (id, mixop, typ, List.rev prev_rules) $ at ] + | r :: rules -> match r.it with + | RuleD (rid, binds, rmixop, exp, prems) -> + if List.exists is_else prems + then + let lhs = match exp.it with + | TupE [lhs; _] -> lhs + | _ -> error exp.at "expected manifest pair" + in + let aux_name = id.it ^ "_before_" ^ rid.it $ rid.at in + let applicable_prev_rules = prev_rules + |> List.map unarize + |> List.filter (not_apart lhs) + |> List.rev in + [ RelD (aux_name, unary_mixfix, typ1, List.rev applicable_prev_rules) $ r.at ] @ + let prems' = List.map (replace_else aux_name lhs) prems in + let rule' = { r with it = RuleD (rid, binds, rmixop, exp, prems') } in + go at id mixop typ typ1 (rule' :: prev_rules) rules + else + go at id mixop typ typ1 (r :: prev_rules) rules + +let rec t_def (def : def) : def list = match def.it with + | RecD defs -> [ { def with it = RecD (List.concat_map t_def defs) } ] + | RelD (id, mixop, typ, rules) -> begin match typ.it with + | TupT [typ1; _typ2] -> + go def.at id mixop typ typ1 [] rules + | _ -> [def] + end + | _ -> [ def ] + +let transform (defs : script) = + List.concat_map t_def defs + diff --git a/spectec/src/middlend/else.mli b/spectec/src/middlend/else.mli new file mode 100644 index 0000000000..542bbf8052 --- /dev/null +++ b/spectec/src/middlend/else.mli @@ -0,0 +1 @@ +val transform : Il.Ast.script -> Il.Ast.script diff --git a/spectec/src/middlend/sideconditions.ml b/spectec/src/middlend/sideconditions.ml index 2efc16feab..003bfbcfc2 100644 --- a/spectec/src/middlend/sideconditions.ml +++ b/spectec/src/middlend/sideconditions.ml @@ -16,7 +16,7 @@ open Il.Ast (* Errors *) -let _error at msg = Source.error at "sideconditions" msg +let error at msg = Source.error at "sideconditions" msg module Env = Map.Make(String) @@ -105,6 +105,10 @@ let rec t_prem env prem = match prem.it with | IterPr (prem, iterexp) -> iter_side_conditions env iterexp @ List.map (fun pr -> IterPr (pr, iterexp) $ no_region) (t_prem env prem) @ t_iterexp env iterexp + | NegPr prem' + -> match t_prem env prem' with + | [] -> [] + | _ -> error prem.at "side condition in negated premise" let t_prems env = List.concat_map (t_prem env) diff --git a/spectec/src/middlend/sub.ml b/spectec/src/middlend/sub.ml index 8950a17f54..13457fb584 100644 --- a/spectec/src/middlend/sub.ml +++ b/spectec/src/middlend/sub.ml @@ -138,6 +138,7 @@ let rec t_prem' env = function | LetPr (e1, e2) -> LetPr (t_exp env e1, t_exp env e2) | ElsePr -> ElsePr | IterPr (prem, iterexp) -> IterPr (t_prem env prem, t_iterexp env iterexp) + | NegPr prem -> NegPr (t_prem env prem) and t_prem env x = { x with it = t_prem' env x.it } diff --git a/spectec/src/middlend/totalize.ml b/spectec/src/middlend/totalize.ml index 53bc54d322..4541b9fb1e 100644 --- a/spectec/src/middlend/totalize.ml +++ b/spectec/src/middlend/totalize.ml @@ -97,6 +97,7 @@ let rec t_prem' env = function | LetPr (e1, e2) -> LetPr (t_exp env e1, t_exp env e2) | ElsePr -> ElsePr | IterPr (prem, iterexp) -> IterPr (t_prem env prem, t_iterexp env iterexp) + | NegPr prem -> NegPr (t_prem env prem) and t_prem env x = { x with it = t_prem' env x.it } diff --git a/spectec/src/middlend/unthe.ml b/spectec/src/middlend/unthe.ml index a272bdb753..7a9c2a8976 100644 --- a/spectec/src/middlend/unthe.ml +++ b/spectec/src/middlend/unthe.ml @@ -182,6 +182,10 @@ and t_prem' n prem : eqns * premise' = let eqns2, iterexp'' = t_iterexp n iterexp' in let iterexp''' = update_iterexp_vars (Il.Free.free_prem prem') iterexp'' in eqns1' @ eqns2, IterPr (prem', iterexp''') + | NegPr prem + -> match t_prem n prem with + | [], prem' -> [], NegPr prem' + | _ -> error prem.at "partial expression (!(e)) in negated premise" let t_prems n k = t_list t_prem n k (fun x -> x) diff --git a/spectec/src/middlend/wild.ml b/spectec/src/middlend/wild.ml index e79b15a8e5..070a67955d 100644 --- a/spectec/src/middlend/wild.ml +++ b/spectec/src/middlend/wild.ml @@ -205,6 +205,9 @@ and t_prem' env prem : binds * premise' = let iterexp', binds1' = under_iterexp iterexp binds1 in let binds2, iterexp'' = t_iterexp env iterexp' in binds1' @ binds2, IterPr (prem', iterexp'') + | NegPr prem -> + let binds1, prem' = t_prem env prem in + binds1, NegPr prem' let t_prems env k = t_list t_prem env k (fun x -> x) diff --git a/spectec/test-haskell/SpecTec.hs b/spectec/test-haskell/SpecTec.hs new file mode 100644 index 0000000000..5c48fa7558 --- /dev/null +++ b/spectec/test-haskell/SpecTec.hs @@ -0,0 +1,958 @@ +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE DuplicateRecordFields #-} +module Test where +import Prelude (Bool, String, undefined, error, Maybe, fromIntegral, (+), (!!)) +import Numeric.Natural (Natural) +type N = Natural + +type Name = String + + + +type Byte = Natural + + + +type U32 = Natural + + + +type Idx = Natural + + + +type Funcidx = Idx + + + +type Globalidx = Idx + + + +type Tableidx = Idx + + + +type Memidx = Idx + + + +type Elemidx = Idx + + + +type Dataidx = Idx + + + +type Labelidx = Idx + + + +type Localidx = Idx + + + +data Numtype + = Numtype_I32 + | Numtype_I64 + | Numtype_F32 + | Numtype_F64 + + + +data Vectype + = Vectype_V128 + + + +data Reftype + = Reftype_FUNCREF + | Reftype_EXTERNREF + + + +data Valtype + = Valtype_I32 + | Valtype_I64 + | Valtype_F32 + | Valtype_F64 + | Valtype_V128 + | Valtype_FUNCREF + | Valtype_EXTERNREF + | Valtype_BOT + +valtype_numtype :: Numtype -> Valtype +valtype_numtype Numtype_I32 = Valtype_I32 +valtype_numtype Numtype_I64 = Valtype_I64 +valtype_numtype Numtype_F32 = Valtype_F32 +valtype_numtype Numtype_F64 = Valtype_F64 + +valtype_reftype :: Reftype -> Valtype +valtype_reftype Reftype_FUNCREF = Valtype_FUNCREF +valtype_reftype Reftype_EXTERNREF = Valtype_EXTERNREF + +valtype_vectype :: Vectype -> Valtype +valtype_vectype Vectype_V128 = Valtype_V128 + + + +data In + = In_I32 + | In_I64 + +numtype_in :: In -> Numtype +numtype_in In_I32 = Numtype_I32 +numtype_in In_I64 = Numtype_I64 + +valtype_in :: In -> Valtype +valtype_in In_I32 = Valtype_I32 +valtype_in In_I64 = Valtype_I64 + + + +data Fn + = Fn_F32 + | Fn_F64 + +numtype_fn :: Fn -> Numtype +numtype_fn Fn_F32 = Numtype_F32 +numtype_fn Fn_F64 = Numtype_F64 + +valtype_fn :: Fn -> Valtype +valtype_fn Fn_F32 = Valtype_F32 +valtype_fn Fn_F64 = Valtype_F64 + + + +type Resulttype = [Valtype] + + + +type Limits = {- mixop: `[%..%]` -} (U32, U32) + + + +type Globaltype = {- mixop: `MUT%?%` -} ((Maybe ()), Valtype) + + + +type Functype = {- mixop: `%->%` -} (Resulttype, Resulttype) + + + +type Tabletype = {- mixop: `%%` -} (Limits, Reftype) + + + +type Memtype = {- mixop: `%I8` -} Limits + + + +type Elemtype = Reftype + + + +type Datatype = {- mixop: OK -} () + + + +data Externtype + = Externtype_GLOBAL Globaltype + | Externtype_FUNC Functype + | Externtype_TABLE Tabletype + | Externtype_MEM Memtype + + + +data Sx + = Sx_U + | Sx_S + + + +data Unop_IXX + = Unop_IXX_CLZ + | Unop_IXX_CTZ + | Unop_IXX_POPCNT + +data Unop_FXX + = Unop_FXX_ABS + | Unop_FXX_NEG + | Unop_FXX_SQRT + | Unop_FXX_CEIL + | Unop_FXX_FLOOR + | Unop_FXX_TRUNC + | Unop_FXX_NEAREST + +data Binop_IXX + = Binop_IXX_ADD + | Binop_IXX_SUB + | Binop_IXX_MUL + | Binop_IXX_DIV Sx + | Binop_IXX_REM Sx + | Binop_IXX_AND + | Binop_IXX_OR + | Binop_IXX_XOR + | Binop_IXX_SHL + | Binop_IXX_SHR Sx + | Binop_IXX_ROTL + | Binop_IXX_ROTR + +data Binop_FXX + = Binop_FXX_ADD + | Binop_FXX_SUB + | Binop_FXX_MUL + | Binop_FXX_DIV + | Binop_FXX_MIN + | Binop_FXX_MAX + | Binop_FXX_COPYSIGN + +data Testop_IXX + = Testop_IXX_EQZ + +data Testop_FXX + +data Relop_IXX + = Relop_IXX_EQ + | Relop_IXX_NE + | Relop_IXX_LT Sx + | Relop_IXX_GT Sx + | Relop_IXX_LE Sx + | Relop_IXX_GE Sx + +data Relop_FXX + = Relop_FXX_EQ + | Relop_FXX_NE + | Relop_FXX_LT + | Relop_FXX_GT + | Relop_FXX_LE + | Relop_FXX_GE + +data Unop_numtype + = Unop_numtype_I Unop_IXX + | Unop_numtype_F Unop_FXX + +data Binop_numtype + = Binop_numtype_I Binop_IXX + | Binop_numtype_F Binop_FXX + +data Testop_numtype + = Testop_numtype_I Testop_IXX + | Testop_numtype_F Testop_FXX + +data Relop_numtype + = Relop_numtype_I Relop_IXX + | Relop_numtype_F Relop_FXX + +data Cvtop + = Cvtop_CONVERT + | Cvtop_REINTERPRET + +type C_numtype = Natural + +type C_vectype = Natural + +type Blocktype = Functype + + + +data Instr + = Instr_UNREACHABLE + | Instr_NOP + | Instr_DROP + | Instr_SELECT (Maybe Valtype) + | Instr_BLOCK (Blocktype, [Instr]) + | Instr_LOOP (Blocktype, [Instr]) + | Instr_IF (Blocktype, [Instr], [Instr]) + | Instr_BR Labelidx + | Instr_BR_IF Labelidx + | Instr_BR_TABLE ([Labelidx], Labelidx) + | Instr_CALL Funcidx + | Instr_CALL_INDIRECT (Tableidx, Functype) + | Instr_RETURN + | Instr_CONST (Numtype, C_numtype) + | Instr_UNOP (Numtype, Unop_numtype) + | Instr_BINOP (Numtype, Binop_numtype) + | Instr_TESTOP (Numtype, Testop_numtype) + | Instr_RELOP (Numtype, Relop_numtype) + | Instr_EXTEND (Numtype, N) + | Instr_CVTOP (Numtype, Cvtop, Numtype, (Maybe Sx)) + | Instr_REF_NULL Reftype + | Instr_REF_FUNC Funcidx + | Instr_REF_IS_NULL + | Instr_LOCAL_GET Localidx + | Instr_LOCAL_SET Localidx + | Instr_LOCAL_TEE Localidx + | Instr_GLOBAL_GET Globalidx + | Instr_GLOBAL_SET Globalidx + | Instr_TABLE_GET Tableidx + | Instr_TABLE_SET Tableidx + | Instr_TABLE_SIZE Tableidx + | Instr_TABLE_GROW Tableidx + | Instr_TABLE_FILL Tableidx + | Instr_TABLE_COPY (Tableidx, Tableidx) + | Instr_TABLE_INIT (Tableidx, Elemidx) + | Instr_ELEM_DROP Elemidx + | Instr_MEMORY_SIZE + | Instr_MEMORY_GROW + | Instr_MEMORY_FILL + | Instr_MEMORY_COPY + | Instr_MEMORY_INIT Dataidx + | Instr_DATA_DROP Dataidx + | Instr_LOAD (Numtype, (Maybe (N, Sx)), U32, U32) + | Instr_STORE (Numtype, (Maybe N), U32, U32) + + + + + + + + + +type Expr = [Instr] + + + + + +data Elemmode + = Elemmode_TABLE (Tableidx, Expr) + | Elemmode_DECLARE + +data Datamode + = Datamode_MEMORY (Memidx, Expr) + +type Func = {- mixop: `FUNC%%*%` -} (Functype, [Valtype], Expr) + + + +type Global = {- mixop: GLOBAL -} (Globaltype, Expr) + + + +type Table = {- mixop: TABLE -} Tabletype + + + +type Mem = {- mixop: MEMORY -} Memtype + + + +type Elem = {- mixop: `ELEM%%*%?` -} (Reftype, [Expr], (Maybe Elemmode)) + + + +type Data = {- mixop: `DATA(*)%*%?` -} ([[Byte]], (Maybe Datamode)) + + + +type Start = {- mixop: START -} Funcidx + + + +data Externuse + = Externuse_FUNC Funcidx + | Externuse_GLOBAL Globalidx + | Externuse_TABLE Tableidx + | Externuse_MEM Memidx + + + +type Export = {- mixop: EXPORT -} (Name, Externuse) + + + +type Import = {- mixop: IMPORT -} (Name, Name, Externtype) + + + +type Module = {- mixop: `MODULE%*%*%*%*%*%*%*%?%*` -} ([Import], [Func], [Global], [Table], [Mem], [Elem], [Data], (Maybe Start), [Export]) + + + +Ki :: () -> Natural +Ki () = 1024 + +min :: (Natural, Natural) -> Natural +min (0, j) = 0 +min (i, 0) = 0 +min ((i + 1), (j + 1)) = undefined {- $min(i, j) -} + +size :: Valtype -> Natural +size Valtype_I32 = 32 +size Valtype_I64 = 64 +size Valtype_F32 = 32 +size Valtype_F64 = 64 +size Valtype_V128 = 128 + + + +test_sub_ATOM_22 :: N -> Natural +test_sub_ATOM_22 n_3_ATOM_y = 0 + +curried_ :: (N, N) -> Natural +curried_ (n_1, n_2) = (n_1 + n_2) + +data Testfuse + = Testfuse_AB_ (Natural, Natural, Natural) + | Testfuse_CD (Natural, Natural, Natural) + | Testfuse_EF (Natural, Natural, Natural) + | Testfuse_GH (Natural, Natural, Natural) + | Testfuse_IJ (Natural, Natural, Natural) + | Testfuse_KL (Natural, Natural, Natural) + | Testfuse_MN (Natural, Natural, Natural) + | Testfuse_OP (Natural, Natural, Natural) + | Testfuse_QR (Natural, Natural, Natural) + +data Context = MkContext + { fUNC :: [Functype] + , gLOBAL :: [Globaltype] + , tABLE :: [Tabletype] + , mEM :: [Memtype] + , eLEM :: [Elemtype] + , dATA :: [Datatype] + , lOCAL :: [Valtype] + , lABEL :: [Resulttype] + , rETURN :: (Maybe Resulttype) + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +type Addr = Natural + + + +type Funcaddr = Addr + + + +type Globaladdr = Addr + + + +type Tableaddr = Addr + + + +type Memaddr = Addr + + + +type Elemaddr = Addr + + + +type Dataaddr = Addr + + + +type Labeladdr = Addr + + + +type Hostaddr = Addr + + + +data Num + = Num_CONST (Numtype, C_numtype) + + + +data Ref + = Ref_REF_NULL Reftype + | Ref_REF_FUNC_ADDR Funcaddr + | Ref_REF_HOST_ADDR Hostaddr + + + +data Val + = Val_CONST (Numtype, C_numtype) + | Val_REF_NULL Reftype + | Val_REF_FUNC_ADDR Funcaddr + | Val_REF_HOST_ADDR Hostaddr + + + +data Result + = Result_VALS [Val] + | Result_TRAP + + + +data Externval + = Externval_FUNC Funcaddr + | Externval_GLOBAL Globaladdr + | Externval_TABLE Tableaddr + | Externval_MEM Memaddr + + + +default_ :: Valtype -> Val +default_ Valtype_I32 = (Val_CONST (Numtype_I32, 0)) +default_ Valtype_I64 = (Val_CONST (Numtype_I64, 0)) +default_ Valtype_F32 = (Val_CONST (Numtype_F32, 0)) +default_ Valtype_F64 = (Val_CONST (Numtype_F64, 0)) +default_ Valtype_FUNCREF = (Val_REF_NULL Reftype_FUNCREF) +default_ Valtype_EXTERNREF = (Val_REF_NULL Reftype_EXTERNREF) + + + +type Exportinst = {- mixop: EXPORT -} (Name, Externval) + +data Moduleinst = MkModuleinst + { fUNC :: [Funcaddr] + , gLOBAL :: [Globaladdr] + , tABLE :: [Tableaddr] + , mEM :: [Memaddr] + , eLEM :: [Elemaddr] + , dATA :: [Dataaddr] + , eXPORT :: [Exportinst] + } + +type Funcinst = {- mixop: `%;%` -} (Moduleinst, Func) + + + +type Globalinst = Val + + + +type Tableinst = [Ref] + + + +type Meminst = [Byte] + + + +type Eleminst = [Ref] + + + +type Datainst = [Byte] + + + + + +data Store = MkStore + { fUNC :: [Funcinst] + , gLOBAL :: [Globalinst] + , tABLE :: [Tableinst] + , mEM :: [Meminst] + , eLEM :: [Eleminst] + , dATA :: [Datainst] + } + + + + + +data Frame = MkFrame + { lOCAL :: [Val] + , mODULE :: Moduleinst + } + + + +type State = {- mixop: `%;%` -} (Store, Frame) + + + +data Admininstr + = Admininstr_UNREACHABLE + | Admininstr_NOP + | Admininstr_DROP + | Admininstr_SELECT (Maybe Valtype) + | Admininstr_BLOCK (Blocktype, [Instr]) + | Admininstr_LOOP (Blocktype, [Instr]) + | Admininstr_IF (Blocktype, [Instr], [Instr]) + | Admininstr_BR Labelidx + | Admininstr_BR_IF Labelidx + | Admininstr_BR_TABLE ([Labelidx], Labelidx) + | Admininstr_CALL Funcidx + | Admininstr_CALL_INDIRECT (Tableidx, Functype) + | Admininstr_RETURN + | Admininstr_CONST (Numtype, C_numtype) + | Admininstr_UNOP (Numtype, Unop_numtype) + | Admininstr_BINOP (Numtype, Binop_numtype) + | Admininstr_TESTOP (Numtype, Testop_numtype) + | Admininstr_RELOP (Numtype, Relop_numtype) + | Admininstr_EXTEND (Numtype, N) + | Admininstr_CVTOP (Numtype, Cvtop, Numtype, (Maybe Sx)) + | Admininstr_REF_NULL Reftype + | Admininstr_REF_FUNC Funcidx + | Admininstr_REF_IS_NULL + | Admininstr_LOCAL_GET Localidx + | Admininstr_LOCAL_SET Localidx + | Admininstr_LOCAL_TEE Localidx + | Admininstr_GLOBAL_GET Globalidx + | Admininstr_GLOBAL_SET Globalidx + | Admininstr_TABLE_GET Tableidx + | Admininstr_TABLE_SET Tableidx + | Admininstr_TABLE_SIZE Tableidx + | Admininstr_TABLE_GROW Tableidx + | Admininstr_TABLE_FILL Tableidx + | Admininstr_TABLE_COPY (Tableidx, Tableidx) + | Admininstr_TABLE_INIT (Tableidx, Elemidx) + | Admininstr_ELEM_DROP Elemidx + | Admininstr_MEMORY_SIZE + | Admininstr_MEMORY_GROW + | Admininstr_MEMORY_FILL + | Admininstr_MEMORY_COPY + | Admininstr_MEMORY_INIT Dataidx + | Admininstr_DATA_DROP Dataidx + | Admininstr_LOAD (Numtype, (Maybe (N, Sx)), U32, U32) + | Admininstr_STORE (Numtype, (Maybe N), U32, U32) + | Admininstr_REF_FUNC_ADDR Funcaddr + | Admininstr_REF_HOST_ADDR Hostaddr + | Admininstr_CALL_ADDR Funcaddr + | Admininstr_LABEL_ (N, [Instr], [Admininstr]) + | Admininstr_FRAME_ (N, Frame, [Admininstr]) + | Admininstr_TRAP + +admininstr_globalinst :: Globalinst -> Admininstr +admininstr_globalinst (Val_CONST (x0, x1)) = (Admininstr_CONST (x0, x1)) +admininstr_globalinst (Val_REF_NULL x) = (Admininstr_REF_NULL x) +admininstr_globalinst (Val_REF_FUNC_ADDR x) = (Admininstr_REF_FUNC_ADDR x) +admininstr_globalinst (Val_REF_HOST_ADDR x) = (Admininstr_REF_HOST_ADDR x) + +admininstr_instr :: Instr -> Admininstr +admininstr_instr Instr_UNREACHABLE = Admininstr_UNREACHABLE +admininstr_instr Instr_NOP = Admininstr_NOP +admininstr_instr Instr_DROP = Admininstr_DROP +admininstr_instr (Instr_SELECT x) = (Admininstr_SELECT x) +admininstr_instr (Instr_BLOCK (x0, x1)) = (Admininstr_BLOCK (x0, x1)) +admininstr_instr (Instr_LOOP (x0, x1)) = (Admininstr_LOOP (x0, x1)) +admininstr_instr (Instr_IF (x0, x1, x2)) = (Admininstr_IF (x0, x1, x2)) +admininstr_instr (Instr_BR x) = (Admininstr_BR x) +admininstr_instr (Instr_BR_IF x) = (Admininstr_BR_IF x) +admininstr_instr (Instr_BR_TABLE (x0, x1)) = (Admininstr_BR_TABLE (x0, x1)) +admininstr_instr (Instr_CALL x) = (Admininstr_CALL x) +admininstr_instr (Instr_CALL_INDIRECT (x0, x1)) = (Admininstr_CALL_INDIRECT (x0, x1)) +admininstr_instr Instr_RETURN = Admininstr_RETURN +admininstr_instr (Instr_CONST (x0, x1)) = (Admininstr_CONST (x0, x1)) +admininstr_instr (Instr_UNOP (x0, x1)) = (Admininstr_UNOP (x0, x1)) +admininstr_instr (Instr_BINOP (x0, x1)) = (Admininstr_BINOP (x0, x1)) +admininstr_instr (Instr_TESTOP (x0, x1)) = (Admininstr_TESTOP (x0, x1)) +admininstr_instr (Instr_RELOP (x0, x1)) = (Admininstr_RELOP (x0, x1)) +admininstr_instr (Instr_EXTEND (x0, x1)) = (Admininstr_EXTEND (x0, x1)) +admininstr_instr (Instr_CVTOP (x0, x1, x2, x3)) = (Admininstr_CVTOP (x0, x1, x2, x3)) +admininstr_instr (Instr_REF_NULL x) = (Admininstr_REF_NULL x) +admininstr_instr (Instr_REF_FUNC x) = (Admininstr_REF_FUNC x) +admininstr_instr Instr_REF_IS_NULL = Admininstr_REF_IS_NULL +admininstr_instr (Instr_LOCAL_GET x) = (Admininstr_LOCAL_GET x) +admininstr_instr (Instr_LOCAL_SET x) = (Admininstr_LOCAL_SET x) +admininstr_instr (Instr_LOCAL_TEE x) = (Admininstr_LOCAL_TEE x) +admininstr_instr (Instr_GLOBAL_GET x) = (Admininstr_GLOBAL_GET x) +admininstr_instr (Instr_GLOBAL_SET x) = (Admininstr_GLOBAL_SET x) +admininstr_instr (Instr_TABLE_GET x) = (Admininstr_TABLE_GET x) +admininstr_instr (Instr_TABLE_SET x) = (Admininstr_TABLE_SET x) +admininstr_instr (Instr_TABLE_SIZE x) = (Admininstr_TABLE_SIZE x) +admininstr_instr (Instr_TABLE_GROW x) = (Admininstr_TABLE_GROW x) +admininstr_instr (Instr_TABLE_FILL x) = (Admininstr_TABLE_FILL x) +admininstr_instr (Instr_TABLE_COPY (x0, x1)) = (Admininstr_TABLE_COPY (x0, x1)) +admininstr_instr (Instr_TABLE_INIT (x0, x1)) = (Admininstr_TABLE_INIT (x0, x1)) +admininstr_instr (Instr_ELEM_DROP x) = (Admininstr_ELEM_DROP x) +admininstr_instr Instr_MEMORY_SIZE = Admininstr_MEMORY_SIZE +admininstr_instr Instr_MEMORY_GROW = Admininstr_MEMORY_GROW +admininstr_instr Instr_MEMORY_FILL = Admininstr_MEMORY_FILL +admininstr_instr Instr_MEMORY_COPY = Admininstr_MEMORY_COPY +admininstr_instr (Instr_MEMORY_INIT x) = (Admininstr_MEMORY_INIT x) +admininstr_instr (Instr_DATA_DROP x) = (Admininstr_DATA_DROP x) +admininstr_instr (Instr_LOAD (x0, x1, x2, x3)) = (Admininstr_LOAD (x0, x1, x2, x3)) +admininstr_instr (Instr_STORE (x0, x1, x2, x3)) = (Admininstr_STORE (x0, x1, x2, x3)) + +admininstr_ref :: Ref -> Admininstr +admininstr_ref (Ref_REF_NULL x) = (Admininstr_REF_NULL x) +admininstr_ref (Ref_REF_FUNC_ADDR x) = (Admininstr_REF_FUNC_ADDR x) +admininstr_ref (Ref_REF_HOST_ADDR x) = (Admininstr_REF_HOST_ADDR x) + +admininstr_val :: Val -> Admininstr +admininstr_val (Val_CONST (x0, x1)) = (Admininstr_CONST (x0, x1)) +admininstr_val (Val_REF_NULL x) = (Admininstr_REF_NULL x) +admininstr_val (Val_REF_FUNC_ADDR x) = (Admininstr_REF_FUNC_ADDR x) +admininstr_val (Val_REF_HOST_ADDR x) = (Admininstr_REF_HOST_ADDR x) + +type Config = {- mixop: `%;%*` -} (State, [Admininstr]) + + + +funcaddr :: State -> [Funcaddr] +funcaddr (s, f) = f.mODULE.fUNC + + + +funcinst :: State -> [Funcinst] +funcinst (s, f) = s.fUNC + + + +func :: (State, Funcidx) -> Funcinst +func ((s, f), x) = (s.fUNC !! (fromIntegral (f.mODULE.fUNC !! (fromIntegral x)))) + + + +global :: (State, Globalidx) -> Globalinst +global ((s, f), x) = (s.gLOBAL !! (fromIntegral (f.mODULE.gLOBAL !! (fromIntegral x)))) + + + +table :: (State, Tableidx) -> Tableinst +table ((s, f), x) = (s.tABLE !! (fromIntegral (f.mODULE.tABLE !! (fromIntegral x)))) + + + +mem :: (State, Memidx) -> Meminst +mem ((s, f), x) = (s.mEM !! (fromIntegral (f.mODULE.mEM !! (fromIntegral x)))) + + + +elem :: (State, Tableidx) -> Eleminst +elem ((s, f), x) = (s.eLEM !! (fromIntegral (f.mODULE.eLEM !! (fromIntegral x)))) + + + +data_ :: (State, Dataidx) -> Datainst +data_ ((s, f), x) = (s.dATA !! (fromIntegral (f.mODULE.dATA !! (fromIntegral x)))) + + + +local :: (State, Localidx) -> Val +local ((s, f), x) = (f.lOCAL !! (fromIntegral x)) + + + +with_local :: (State, Localidx, Val) -> State +with_local ((s, f), x, v) = (s, undefined {- f[LOCAL_frame[x] = v] -}) + + + +with_global :: (State, Globalidx, Val) -> State +with_global ((s, f), x, v) = (undefined {- s[GLOBAL_store[f.MODULE_frame.GLOBAL_moduleinst[x]] = v] -}, f) + + + +with_table :: (State, Tableidx, Natural, Ref) -> State +with_table ((s, f), x, i, r) = (undefined {- s[TABLE_store[f.MODULE_frame.TABLE_moduleinst[x]][i] = r] -}, f) + + + +with_tableext :: (State, Tableidx, [Ref]) -> State +with_tableext ((s, f), x, r) = (undefined {- s[TABLE_store[f.MODULE_frame.TABLE_moduleinst[x]] =.. r*{r}] -}, f) + + + +with_mem :: (State, Tableidx, Natural, Natural, [Byte]) -> State +with_mem ((s, f), x, i, j, b) = (undefined {- s[MEM_store[f.MODULE_frame.MEM_moduleinst[x]][i : j] = b*{b}] -}, f) + + + +with_memext :: (State, Tableidx, [Byte]) -> State +with_memext ((s, f), x, b) = (undefined {- s[MEM_store[f.MODULE_frame.MEM_moduleinst[x]] =.. b*{b}] -}, f) + + + +with_elem :: (State, Elemidx, [Ref]) -> State +with_elem ((s, f), x, r) = (undefined {- s[ELEM_store[f.MODULE_frame.ELEM_moduleinst[x]] = r*{r}] -}, f) + + + +with_data :: (State, Dataidx, [Byte]) -> State +with_data ((s, f), x, b) = (undefined {- s[DATA_store[f.MODULE_frame.DATA_moduleinst[x]] = b*{b}] -}, f) + + + + + +data E + = E_HOLE + | E_SEQ ([Val], E, [Instr]) + | E_LABEL_ (N, [Instr], E) + + + +unop :: (Unop_numtype, Numtype, C_numtype) -> [C_numtype] +unop = error "function without clauses" + + + +binop :: (Binop_numtype, Numtype, C_numtype, C_numtype) -> [C_numtype] +binop = error "function without clauses" + + + +testop :: (Testop_numtype, Numtype, C_numtype) -> C_numtype +testop = error "function without clauses" + + + +relop :: (Relop_numtype, Numtype, C_numtype, C_numtype) -> C_numtype +relop = error "function without clauses" + + + +ext :: (Natural, Natural, Sx, C_numtype) -> C_numtype +ext = error "function without clauses" + + + +cvtop :: (Numtype, Cvtop, Numtype, (Maybe Sx), C_numtype) -> [C_numtype] +cvtop = error "function without clauses" + + + +wrap_ :: ((Natural, Natural), C_numtype) -> Natural +wrap_ = error "function without clauses" + +bytes_ :: (Natural, C_numtype) -> [Byte] +bytes_ = error "function without clauses" + + + + + + + + + + + diff --git a/spectec/test-haskell/TEST.md b/spectec/test-haskell/TEST.md new file mode 100644 index 0000000000..95ed821e54 --- /dev/null +++ b/spectec/test-haskell/TEST.md @@ -0,0 +1,675 @@ +# Preview + +```sh +$ dune exec ../src/exe-watsup/main.exe -- --haskell ../spec/*.watsup -o Test.hs +$ cat Test.hs +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE DuplicateRecordFields #-} +module Test where +import Prelude (Bool, String, undefined, error, Maybe, fromIntegral, (+), (!!)) +import Numeric.Natural (Natural) +type N = Natural + +type Name = String + +type Byte = Natural + +type U32 = Natural + +type Idx = Natural + +type Funcidx = Idx + +type Globalidx = Idx + +type Tableidx = Idx + +type Memidx = Idx + +type Elemidx = Idx + +type Dataidx = Idx + +type Labelidx = Idx + +type Localidx = Idx + +data Numtype + = Numtype_I32 + | Numtype_I64 + | Numtype_F32 + | Numtype_F64 + +data Vectype + = Vectype_V128 + +data Reftype + = Reftype_FUNCREF + | Reftype_EXTERNREF + +data Valtype + = Valtype_I32 + | Valtype_I64 + | Valtype_F32 + | Valtype_F64 + | Valtype_V128 + | Valtype_FUNCREF + | Valtype_EXTERNREF + | Valtype_BOT + +valtype_numtype :: Numtype -> Valtype +valtype_numtype Numtype_I32 = Valtype_I32 +valtype_numtype Numtype_I64 = Valtype_I64 +valtype_numtype Numtype_F32 = Valtype_F32 +valtype_numtype Numtype_F64 = Valtype_F64 + +valtype_vectype :: Vectype -> Valtype +valtype_vectype Vectype_V128 = Valtype_V128 + +valtype_reftype :: Reftype -> Valtype +valtype_reftype Reftype_FUNCREF = Valtype_FUNCREF +valtype_reftype Reftype_EXTERNREF = Valtype_EXTERNREF + +data In + = In_I32 + | In_I64 + +numtype_in :: In -> Numtype +numtype_in In_I32 = Numtype_I32 +numtype_in In_I64 = Numtype_I64 + +valtype_in :: In -> Valtype +valtype_in In_I32 = Valtype_I32 +valtype_in In_I64 = Valtype_I64 + +data Fn + = Fn_F32 + | Fn_F64 + +numtype_fn :: Fn -> Numtype +numtype_fn Fn_F32 = Numtype_F32 +numtype_fn Fn_F64 = Numtype_F64 + +valtype_fn :: Fn -> Valtype +valtype_fn Fn_F32 = Valtype_F32 +valtype_fn Fn_F64 = Valtype_F64 + +type Resulttype = [Valtype] + +type Limits = {- mixop: `[%..%]` -} (U32, U32) + +type Mutflag = {- mixop: MUT -} () + +type Globaltype = {- mixop: `%?%` -} ((Maybe Mutflag), Valtype) + +type Functype = {- mixop: `%->%` -} (Resulttype, Resulttype) + +type Tabletype = {- mixop: `%%` -} (Limits, Reftype) + +type Memtype = {- mixop: `%I8` -} Limits + +type Elemtype = Reftype + +type Datatype = {- mixop: OK -} () + +data Externtype + = Externtype_GLOBAL Globaltype + | Externtype_FUNC Functype + | Externtype_TABLE Tabletype + | Externtype_MEMORY Memtype + +data Sx + = Sx_U + | Sx_S + +data Unop_IXX + = Unop_IXX_CLZ + | Unop_IXX_CTZ + | Unop_IXX_POPCNT + +data Unop_FXX + = Unop_FXX_ABS + | Unop_FXX_NEG + | Unop_FXX_SQRT + | Unop_FXX_CEIL + | Unop_FXX_FLOOR + | Unop_FXX_TRUNC + | Unop_FXX_NEAREST + +data Binop_IXX + = Binop_IXX_ADD + | Binop_IXX_SUB + | Binop_IXX_MUL + | Binop_IXX_DIV Sx + | Binop_IXX_REM Sx + | Binop_IXX_AND + | Binop_IXX_OR + | Binop_IXX_XOR + | Binop_IXX_SHL + | Binop_IXX_SHR Sx + | Binop_IXX_ROTL + | Binop_IXX_ROTR + +data Binop_FXX + = Binop_FXX_ADD + | Binop_FXX_SUB + | Binop_FXX_MUL + | Binop_FXX_DIV + | Binop_FXX_MIN + | Binop_FXX_MAX + | Binop_FXX_COPYSIGN + +data Testop_IXX + = Testop_IXX_EQZ + +data Testop_FXX + +data Relop_IXX + = Relop_IXX_EQ + | Relop_IXX_NE + | Relop_IXX_LT Sx + | Relop_IXX_GT Sx + | Relop_IXX_LE Sx + | Relop_IXX_GE Sx + +data Relop_FXX + = Relop_FXX_EQ + | Relop_FXX_NE + | Relop_FXX_LT + | Relop_FXX_GT + | Relop_FXX_LE + | Relop_FXX_GE + +data Unop_numtype + = Unop_numtype_I Unop_IXX + | Unop_numtype_F Unop_FXX + +data Binop_numtype + = Binop_numtype_I Binop_IXX + | Binop_numtype_F Binop_FXX + +data Testop_numtype + = Testop_numtype_I Testop_IXX + | Testop_numtype_F Testop_FXX + +data Relop_numtype + = Relop_numtype_I Relop_IXX + | Relop_numtype_F Relop_FXX + +data Cvtop + = Cvtop_CONVERT + | Cvtop_REINTERPRET + +type C_numtype = Natural + +type C_vectype = Natural + +type Blocktype = Functype + +data Instr + = Instr_UNREACHABLE + | Instr_NOP + | Instr_DROP + | Instr_SELECT (Maybe Valtype) + | Instr_BLOCK (Blocktype, [Instr]) + | Instr_LOOP (Blocktype, [Instr]) + | Instr_IF (Blocktype, [Instr], [Instr]) + | Instr_BR Labelidx + | Instr_BR_IF Labelidx + | Instr_BR_TABLE ([Labelidx], Labelidx) + | Instr_CALL Funcidx + | Instr_CALL_INDIRECT (Tableidx, Functype) + | Instr_RETURN + | Instr_CONST (Numtype, C_numtype) + | Instr_UNOP (Numtype, Unop_numtype) + | Instr_BINOP (Numtype, Binop_numtype) + | Instr_TESTOP (Numtype, Testop_numtype) + | Instr_RELOP (Numtype, Relop_numtype) + | Instr_EXTEND (Numtype, N) + | Instr_CVTOP (Numtype, Cvtop, Numtype, (Maybe Sx)) + | Instr_REF_NULL Reftype + | Instr_REF_FUNC Funcidx + | Instr_REF_IS_NULL + | Instr_LOCAL_GET Localidx + | Instr_LOCAL_SET Localidx + | Instr_LOCAL_TEE Localidx + | Instr_GLOBAL_GET Globalidx + | Instr_GLOBAL_SET Globalidx + | Instr_TABLE_GET Tableidx + | Instr_TABLE_SET Tableidx + | Instr_TABLE_SIZE Tableidx + | Instr_TABLE_GROW Tableidx + | Instr_TABLE_FILL Tableidx + | Instr_TABLE_COPY (Tableidx, Tableidx) + | Instr_TABLE_INIT (Tableidx, Elemidx) + | Instr_ELEM_DROP Elemidx + | Instr_MEMORY_SIZE + | Instr_MEMORY_GROW + | Instr_MEMORY_FILL + | Instr_MEMORY_COPY + | Instr_MEMORY_INIT Dataidx + | Instr_DATA_DROP Dataidx + | Instr_LOAD (Numtype, (Maybe (N, Sx)), Natural, Natural) + | Instr_STORE (Numtype, (Maybe N), Natural, Natural) + +type Expr = [Instr] + +data Elemmode + = Elemmode_TABLE (Tableidx, Expr) + | Elemmode_DECLARE + +data Datamode + = Datamode_MEMORY (Memidx, Expr) + +type Func = {- mixop: `FUNC%%*%` -} (Functype, [Valtype], Expr) + +type Global = {- mixop: GLOBAL -} (Globaltype, Expr) + +type Table = {- mixop: TABLE -} Tabletype + +type Mem = {- mixop: MEMORY -} Memtype + +type Elem = {- mixop: `ELEM%%*%?` -} (Reftype, [Expr], (Maybe Elemmode)) + +type Data = {- mixop: `DATA(*)%*%?` -} ([[Byte]], (Maybe Datamode)) + +type Start = {- mixop: START -} Funcidx + +data Externuse + = Externuse_FUNC Funcidx + | Externuse_GLOBAL Globalidx + | Externuse_TABLE Tableidx + | Externuse_MEMORY Memidx + +type Export = {- mixop: EXPORT -} (Name, Externuse) + +type Import = {- mixop: IMPORT -} (Name, Name, Externtype) + +type Module = {- mixop: `MODULE%*%*%*%*%*%*%*%*%*` -} ([Import], [Func], [Global], [Table], [Mem], [Elem], [Data], [Start], [Export]) + +size :: Valtype -> Natural +size Valtype_I32 = 32 +size Valtype_I64 = 64 +size Valtype_F32 = 32 +size Valtype_F64 = 64 +size Valtype_V128 = 128 + +test_sub_ATOM_22 :: N -> Natural +test_sub_ATOM_22 n_3_ATOM_y = 0 + +curried_ :: (N, N) -> Natural +curried_ (n_1, n_2) = (n_1 + n_2) + +data Testfuse + = Testfuse_AB_ (Natural, Natural, Natural) + | Testfuse_CD (Natural, Natural, Natural) + | Testfuse_EF (Natural, Natural, Natural) + | Testfuse_GH (Natural, Natural, Natural) + | Testfuse_IJ (Natural, Natural, Natural) + | Testfuse_KL (Natural, Natural, Natural) + | Testfuse_MN (Natural, Natural, Natural) + | Testfuse_OP (Natural, Natural, Natural) + | Testfuse_QR (Natural, Natural, Natural) + +data Context = MkContext + { fUNC :: [Functype] + , gLOBAL :: [Globaltype] + , tABLE :: [Tabletype] + , mEM :: [Memtype] + , eLEM :: [Elemtype] + , dATA :: [Datatype] + , lOCAL :: [Valtype] + , lABEL :: [Resulttype] + , rETURN :: (Maybe Resulttype) + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +type Addr = Natural + +type Funcaddr = Addr + +type Globaladdr = Addr + +type Tableaddr = Addr + +type Memaddr = Addr + +type Elemaddr = Addr + +type Dataaddr = Addr + +type Labeladdr = Addr + +type Hostaddr = Addr + +data Num + = Num_CONST (Numtype, C_numtype) + +data Ref + = Ref_REF_NULL Reftype + | Ref_REF_FUNC_ADDR Funcaddr + | Ref_REF_HOST_ADDR Hostaddr + +data Val + = Val_CONST (Numtype, C_numtype) + | Val_REF_NULL Reftype + | Val_REF_FUNC_ADDR Funcaddr + | Val_REF_HOST_ADDR Hostaddr + +val_num :: Num -> Val +val_num (Num_CONST x) = (Val_CONST x) + +val_ref :: Ref -> Val +val_ref (Ref_REF_NULL x) = (Val_REF_NULL x) +val_ref (Ref_REF_FUNC_ADDR x) = (Val_REF_FUNC_ADDR x) +val_ref (Ref_REF_HOST_ADDR x) = (Val_REF_HOST_ADDR x) + +data Result + = Result_VALS [Val] + | Result_TRAP + +data Externval + = Externval_FUNC Funcaddr + | Externval_GLOBAL Globaladdr + | Externval_TABLE Tableaddr + | Externval_MEM Memaddr + +default_ :: Valtype -> Val +default_ Valtype_I32 = (Val_CONST (Numtype_I32, 0)) +default_ Valtype_I64 = (Val_CONST (Numtype_I64, 0)) +default_ Valtype_F32 = (Val_CONST (Numtype_F32, 0)) +default_ Valtype_F64 = (Val_CONST (Numtype_F64, 0)) +default_ Valtype_FUNCREF = (Val_REF_NULL Reftype_FUNCREF) +default_ Valtype_EXTERNREF = (Val_REF_NULL Reftype_EXTERNREF) + +type Exportinst = {- mixop: EXPORT -} (Name, Externval) + +data Moduleinst = MkModuleinst + { fUNC :: [Funcaddr] + , gLOBAL :: [Globaladdr] + , tABLE :: [Tableaddr] + , mEM :: [Memaddr] + , eLEM :: [Elemaddr] + , dATA :: [Dataaddr] + , eXPORT :: [Exportinst] + } + +type Funcinst = {- mixop: `%;%` -} (Moduleinst, Func) + +type Globalinst = Val + +type Tableinst = [Ref] + +type Meminst = [Byte] + +type Eleminst = [Ref] + +type Datainst = [Byte] + +data Store = MkStore + { fUNC :: [Funcinst] + , gLOBAL :: [Globalinst] + , tABLE :: [Tableinst] + , mEM :: [Meminst] + , eLEM :: [Eleminst] + , dATA :: [Datainst] + } + +data Frame = MkFrame + { lOCAL :: [Val] + , mODULE :: Moduleinst + } + +type State = {- mixop: `%;%` -} (Store, Frame) + +data Admininstr + = Admininstr_UNREACHABLE + | Admininstr_NOP + | Admininstr_DROP + | Admininstr_SELECT (Maybe Valtype) + | Admininstr_BLOCK (Blocktype, [Instr]) + | Admininstr_LOOP (Blocktype, [Instr]) + | Admininstr_IF (Blocktype, [Instr], [Instr]) + | Admininstr_BR Labelidx + | Admininstr_BR_IF Labelidx + | Admininstr_BR_TABLE ([Labelidx], Labelidx) + | Admininstr_CALL Funcidx + | Admininstr_CALL_INDIRECT (Tableidx, Functype) + | Admininstr_RETURN + | Admininstr_CONST (Numtype, C_numtype) + | Admininstr_UNOP (Numtype, Unop_numtype) + | Admininstr_BINOP (Numtype, Binop_numtype) + | Admininstr_TESTOP (Numtype, Testop_numtype) + | Admininstr_RELOP (Numtype, Relop_numtype) + | Admininstr_EXTEND (Numtype, N) + | Admininstr_CVTOP (Numtype, Cvtop, Numtype, (Maybe Sx)) + | Admininstr_REF_NULL Reftype + | Admininstr_REF_FUNC Funcidx + | Admininstr_REF_IS_NULL + | Admininstr_LOCAL_GET Localidx + | Admininstr_LOCAL_SET Localidx + | Admininstr_LOCAL_TEE Localidx + | Admininstr_GLOBAL_GET Globalidx + | Admininstr_GLOBAL_SET Globalidx + | Admininstr_TABLE_GET Tableidx + | Admininstr_TABLE_SET Tableidx + | Admininstr_TABLE_SIZE Tableidx + | Admininstr_TABLE_GROW Tableidx + | Admininstr_TABLE_FILL Tableidx + | Admininstr_TABLE_COPY (Tableidx, Tableidx) + | Admininstr_TABLE_INIT (Tableidx, Elemidx) + | Admininstr_ELEM_DROP Elemidx + | Admininstr_MEMORY_SIZE + | Admininstr_MEMORY_GROW + | Admininstr_MEMORY_FILL + | Admininstr_MEMORY_COPY + | Admininstr_MEMORY_INIT Dataidx + | Admininstr_DATA_DROP Dataidx + | Admininstr_LOAD (Numtype, (Maybe (N, Sx)), Natural, Natural) + | Admininstr_STORE (Numtype, (Maybe N), Natural, Natural) + | Admininstr_REF_FUNC_ADDR Funcaddr + | Admininstr_REF_HOST_ADDR Hostaddr + | Admininstr_CALL_ADDR Funcaddr + | Admininstr_LABEL_ (N, [Instr], [Admininstr]) + | Admininstr_FRAME_ (N, Frame, [Admininstr]) + | Admininstr_TRAP + +admininstr_instr :: Instr -> Admininstr +admininstr_instr Instr_UNREACHABLE = Admininstr_UNREACHABLE +admininstr_instr Instr_NOP = Admininstr_NOP +admininstr_instr Instr_DROP = Admininstr_DROP +admininstr_instr (Instr_SELECT x) = (Admininstr_SELECT x) +admininstr_instr (Instr_BLOCK x) = (Admininstr_BLOCK x) +admininstr_instr (Instr_LOOP x) = (Admininstr_LOOP x) +admininstr_instr (Instr_IF x) = (Admininstr_IF x) +admininstr_instr (Instr_BR x) = (Admininstr_BR x) +admininstr_instr (Instr_BR_IF x) = (Admininstr_BR_IF x) +admininstr_instr (Instr_BR_TABLE x) = (Admininstr_BR_TABLE x) +admininstr_instr (Instr_CALL x) = (Admininstr_CALL x) +admininstr_instr (Instr_CALL_INDIRECT x) = (Admininstr_CALL_INDIRECT x) +admininstr_instr Instr_RETURN = Admininstr_RETURN +admininstr_instr (Instr_CONST x) = (Admininstr_CONST x) +admininstr_instr (Instr_UNOP x) = (Admininstr_UNOP x) +admininstr_instr (Instr_BINOP x) = (Admininstr_BINOP x) +admininstr_instr (Instr_TESTOP x) = (Admininstr_TESTOP x) +admininstr_instr (Instr_RELOP x) = (Admininstr_RELOP x) +admininstr_instr (Instr_EXTEND x) = (Admininstr_EXTEND x) +admininstr_instr (Instr_CVTOP x) = (Admininstr_CVTOP x) +admininstr_instr (Instr_REF_NULL x) = (Admininstr_REF_NULL x) +admininstr_instr (Instr_REF_FUNC x) = (Admininstr_REF_FUNC x) +admininstr_instr Instr_REF_IS_NULL = Admininstr_REF_IS_NULL +admininstr_instr (Instr_LOCAL_GET x) = (Admininstr_LOCAL_GET x) +admininstr_instr (Instr_LOCAL_SET x) = (Admininstr_LOCAL_SET x) +admininstr_instr (Instr_LOCAL_TEE x) = (Admininstr_LOCAL_TEE x) +admininstr_instr (Instr_GLOBAL_GET x) = (Admininstr_GLOBAL_GET x) +admininstr_instr (Instr_GLOBAL_SET x) = (Admininstr_GLOBAL_SET x) +admininstr_instr (Instr_TABLE_GET x) = (Admininstr_TABLE_GET x) +admininstr_instr (Instr_TABLE_SET x) = (Admininstr_TABLE_SET x) +admininstr_instr (Instr_TABLE_SIZE x) = (Admininstr_TABLE_SIZE x) +admininstr_instr (Instr_TABLE_GROW x) = (Admininstr_TABLE_GROW x) +admininstr_instr (Instr_TABLE_FILL x) = (Admininstr_TABLE_FILL x) +admininstr_instr (Instr_TABLE_COPY x) = (Admininstr_TABLE_COPY x) +admininstr_instr (Instr_TABLE_INIT x) = (Admininstr_TABLE_INIT x) +admininstr_instr (Instr_ELEM_DROP x) = (Admininstr_ELEM_DROP x) +admininstr_instr Instr_MEMORY_SIZE = Admininstr_MEMORY_SIZE +admininstr_instr Instr_MEMORY_GROW = Admininstr_MEMORY_GROW +admininstr_instr Instr_MEMORY_FILL = Admininstr_MEMORY_FILL +admininstr_instr Instr_MEMORY_COPY = Admininstr_MEMORY_COPY +admininstr_instr (Instr_MEMORY_INIT x) = (Admininstr_MEMORY_INIT x) +admininstr_instr (Instr_DATA_DROP x) = (Admininstr_DATA_DROP x) +admininstr_instr (Instr_LOAD x) = (Admininstr_LOAD x) +admininstr_instr (Instr_STORE x) = (Admininstr_STORE x) + +admininstr_val :: Val -> Admininstr +admininstr_val (Val_CONST x) = (Admininstr_CONST x) +admininstr_val (Val_REF_NULL x) = (Admininstr_REF_NULL x) +admininstr_val (Val_REF_FUNC_ADDR x) = (Admininstr_REF_FUNC_ADDR x) +admininstr_val (Val_REF_HOST_ADDR x) = (Admininstr_REF_HOST_ADDR x) + +admininstr_ref :: Ref -> Admininstr +admininstr_ref (Ref_REF_NULL x) = (Admininstr_REF_NULL x) +admininstr_ref (Ref_REF_FUNC_ADDR x) = (Admininstr_REF_FUNC_ADDR x) +admininstr_ref (Ref_REF_HOST_ADDR x) = (Admininstr_REF_HOST_ADDR x) + +admininstr_globalinst :: Globalinst -> Admininstr +admininstr_globalinst x = undefined {- $admininstr_val(x) -} + +type Config = {- mixop: `%;%*` -} (State, [Admininstr]) + +funcaddr :: State -> [Funcaddr] +funcaddr (s, f) = f.mODULE.fUNC + +funcinst :: State -> [Funcinst] +funcinst (s, f) = s.fUNC + +func :: (State, Funcidx) -> Funcinst +func ((s, f), x) = (s.fUNC !! (fromIntegral (f.mODULE.fUNC !! (fromIntegral x)))) + +global :: (State, Globalidx) -> Globalinst +global ((s, f), x) = (s.gLOBAL !! (fromIntegral (f.mODULE.gLOBAL !! (fromIntegral x)))) + +table :: (State, Tableidx) -> Tableinst +table ((s, f), x) = (s.tABLE !! (fromIntegral (f.mODULE.tABLE !! (fromIntegral x)))) + +mem :: (State, Memidx) -> Meminst +mem ((s, f), x) = (s.mEM !! (fromIntegral (f.mODULE.mEM !! (fromIntegral x)))) + +elem :: (State, Tableidx) -> Eleminst +elem ((s, f), x) = (s.eLEM !! (fromIntegral (f.mODULE.eLEM !! (fromIntegral x)))) + +data_ :: (State, Dataidx) -> Datainst +data_ ((s, f), x) = (s.dATA !! (fromIntegral (f.mODULE.dATA !! (fromIntegral x)))) + +local :: (State, Localidx) -> Val +local ((s, f), x) = (f.lOCAL !! (fromIntegral x)) + +with_local :: (State, Localidx, Val) -> State +with_local ((s, f), x, v) = (s, undefined {- f[LOCAL[x] = v] -}) + +with_global :: (State, Globalidx, Val) -> State +with_global ((s, f), x, v) = (undefined {- s[GLOBAL[f.MODULE_frame.GLOBAL_moduleinst[x]] = v] -}, f) + +with_table :: (State, Tableidx, N, Ref) -> State +with_table ((s, f), x, i, r) = (undefined {- s[TABLE[f.MODULE_frame.TABLE_moduleinst[x]][i] = r] -}, f) + +with_tableext :: (State, Tableidx, [Ref]) -> State +with_tableext ((s, f), x, r) = (undefined {- s[TABLE[f.MODULE_frame.TABLE_moduleinst[x]] =.. r*{r}] -}, f) + +with_elem :: (State, Elemidx, [Ref]) -> State +with_elem ((s, f), x, r) = (undefined {- s[TABLE[f.MODULE_frame.TABLE_moduleinst[x]] = r*{r}] -}, f) + +data E + = E_HOLE + | E_SEQ ([Val], E, [Instr]) + | E_LABEL_ (N, [Instr], E) + +unop :: (Unop_numtype, Numtype, C_numtype) -> [C_numtype] +unop = error "function without clauses" + +binop :: (Binop_numtype, Numtype, C_numtype, C_numtype) -> [C_numtype] +binop = error "function without clauses" + +testop :: (Testop_numtype, Numtype, C_numtype) -> C_numtype +testop = error "function without clauses" + +relop :: (Relop_numtype, Numtype, C_numtype, C_numtype) -> C_numtype +relop = error "function without clauses" + +ext :: (Natural, Natural, Sx, C_numtype) -> C_numtype +ext = error "function without clauses" + +cvtop :: (Numtype, Cvtop, Numtype, (Maybe Sx), C_numtype) -> [C_numtype] +cvtop = error "function without clauses" + + + + + +$ ghc -c Test.hs +``` diff --git a/spectec/test-haskell/dune b/spectec/test-haskell/dune new file mode 100644 index 0000000000..3430d9e584 --- /dev/null +++ b/spectec/test-haskell/dune @@ -0,0 +1,22 @@ +(rule + (targets stderr.current SpecTec.hs.current) + (deps + (file ../src/exe-watsup/main.exe) + (glob_files ../spec/*.watsup) + ) + (action + (progn + (write-file SpecTec.hs.current "not generated") + (with-stderr-to stderr.current (run %{deps} --haskell -o SpecTec.hs.current)) + ) + ) +) + +(rule + (alias runtest) + (action (diff stderr.expected stderr.current)) +) +(rule + (alias runtest) + (action (diff SpecTec.hs SpecTec.hs.current)) +) diff --git a/spectec/test-lean4/SpecTec.lean b/spectec/test-lean4/SpecTec.lean new file mode 100644 index 0000000000..c6095c8364 --- /dev/null +++ b/spectec/test-lean4/SpecTec.lean @@ -0,0 +1,1793 @@ +/- Lean 4 export -/ + +/- A little prelude -/ + +set_option linter.unusedVariables false + +instance : Append (Option a) where + append := fun o1 o2 => match o1 with | none => o2 | _ => o1 + + +inductive Forall (R : α → Prop) : List α → Prop + | nil : Forall R [] + | cons {a l₁} : R a → Forall R l₁ → Forall R (a :: l₁) +attribute [simp] Forall.nil +inductive Forall₂ (R : α → β → Prop) : List α → List β → Prop + | nil : Forall₂ R [] [] + | cons {a b l₁ l₂} : R a b → Forall₂ R l₁ l₂ → Forall₂ R (a :: l₁) (b :: l₂) +attribute [simp] Forall₂.nil +def Option.zipWith : (α → β → γ) → Option α → Option β → Option γ + | f, (some x), (some y) => some (f x y) + | _, _, _ => none +def Option.toList : Option α → List α + | none => List.nil + | some x => [x] +def List.upd : List α → Nat → α → List α + | [], _, _ => [] + | x::xs, 0, y => y :: xs + | x::xs, n+1, y => x :: xs.upd n y +def List.upds : List α → Nat → Nat → List α → List α + | xs, n, m, ys => xs.take n ++ ys ++ xs.drop (n + m) +def List.slice : List α → Nat → Nat → List α + | xs, n, m => (xs.drop n) + + +/- Now, the generated code -/ + +@[reducible] def N := Nat + +@[reducible] def Name := String + + + +@[reducible] def Byte := Nat + + + +@[reducible] def U32 := Nat + + + +@[reducible] def Idx := Nat + + + +@[reducible] def Funcidx := Idx + + + +@[reducible] def Globalidx := Idx + + + +@[reducible] def Tableidx := Idx + + + +@[reducible] def Memidx := Idx + + + +@[reducible] def Elemidx := Idx + + + +@[reducible] def Dataidx := Idx + + + +@[reducible] def Labelidx := Idx + + + +@[reducible] def Localidx := Idx + + + +inductive Numtype where + | I32 : Numtype + | I64 : Numtype + | F32 : Numtype + | F64 : Numtype + deriving Inhabited, BEq + + + +inductive Vectype where + | V128 : Vectype + deriving Inhabited, BEq + + + +inductive Reftype where + | FUNCREF : Reftype + | EXTERNREF : Reftype + deriving Inhabited, BEq + + + +inductive Valtype where + | I32 : Valtype + | I64 : Valtype + | F32 : Valtype + | F64 : Valtype + | V128 : Valtype + | FUNCREF : Valtype + | EXTERNREF : Valtype + | BOT : Valtype + deriving Inhabited, BEq + +def «$valtype_numtype» : Numtype -> Valtype + | Numtype.I32 => Valtype.I32 + | Numtype.I64 => Valtype.I64 + | Numtype.F32 => Valtype.F32 + | Numtype.F64 => Valtype.F64 + +def «$valtype_reftype» : Reftype -> Valtype + | Reftype.FUNCREF => Valtype.FUNCREF + | Reftype.EXTERNREF => Valtype.EXTERNREF + +def «$valtype_vectype» : Vectype -> Valtype + | Vectype.V128 => Valtype.V128 + + + +inductive In where + | I32 : In + | I64 : In + deriving Inhabited, BEq + +def «$numtype_in» : In -> Numtype + | In.I32 => Numtype.I32 + | In.I64 => Numtype.I64 + +def «$valtype_in» : In -> Valtype + | In.I32 => Valtype.I32 + | In.I64 => Valtype.I64 + + + +inductive Fn where + | F32 : Fn + | F64 : Fn + deriving Inhabited, BEq + +def «$numtype_fn» : Fn -> Numtype + | Fn.F32 => Numtype.F32 + | Fn.F64 => Numtype.F64 + +def «$valtype_fn» : Fn -> Valtype + | Fn.F32 => Valtype.F32 + | Fn.F64 => Valtype.F64 + + + +@[reducible] def Resulttype := (List Valtype) + + + +@[reducible] def Limits := /- mixop: `[%..%]` -/ (U32 × U32) + + + +@[reducible] def Globaltype := /- mixop: `MUT%?%` -/ ((Option Unit) × Valtype) + + + +@[reducible] def Functype := /- mixop: `%->%` -/ (Resulttype × Resulttype) + + + +@[reducible] def Tabletype := /- mixop: `%%` -/ (Limits × Reftype) + + + +@[reducible] def Memtype := /- mixop: `%I8` -/ Limits + + + +@[reducible] def Elemtype := Reftype + + + +@[reducible] def Datatype := /- mixop: OK -/ Unit + + + +inductive Externtype where + | GLOBAL : Globaltype -> Externtype + | FUNC : Functype -> Externtype + | TABLE : Tabletype -> Externtype + | MEM : Memtype -> Externtype + deriving Inhabited, BEq + + + +inductive Sx where + | U : Sx + | S : Sx + deriving Inhabited, BEq + + + +inductive Unop_IXX where + | CLZ : Unop_IXX + | CTZ : Unop_IXX + | POPCNT : Unop_IXX + deriving Inhabited, BEq + +inductive Unop_FXX where + | ABS : Unop_FXX + | NEG : Unop_FXX + | SQRT : Unop_FXX + | CEIL : Unop_FXX + | FLOOR : Unop_FXX + | TRUNC : Unop_FXX + | NEAREST : Unop_FXX + deriving Inhabited, BEq + +inductive Binop_IXX where + | ADD : Binop_IXX + | SUB : Binop_IXX + | MUL : Binop_IXX + | DIV : Sx -> Binop_IXX + | REM : Sx -> Binop_IXX + | AND : Binop_IXX + | OR : Binop_IXX + | XOR : Binop_IXX + | SHL : Binop_IXX + | SHR : Sx -> Binop_IXX + | ROTL : Binop_IXX + | ROTR : Binop_IXX + deriving Inhabited, BEq + +inductive Binop_FXX where + | ADD : Binop_FXX + | SUB : Binop_FXX + | MUL : Binop_FXX + | DIV : Binop_FXX + | MIN : Binop_FXX + | MAX : Binop_FXX + | COPYSIGN : Binop_FXX + deriving Inhabited, BEq + +inductive Testop_IXX where + | EQZ : Testop_IXX + deriving Inhabited, BEq + +inductive Testop_FXX where + deriving BEq + +inductive Relop_IXX where + | EQ : Relop_IXX + | NE : Relop_IXX + | LT : Sx -> Relop_IXX + | GT : Sx -> Relop_IXX + | LE : Sx -> Relop_IXX + | GE : Sx -> Relop_IXX + deriving Inhabited, BEq + +inductive Relop_FXX where + | EQ : Relop_FXX + | NE : Relop_FXX + | LT : Relop_FXX + | GT : Relop_FXX + | LE : Relop_FXX + | GE : Relop_FXX + deriving Inhabited, BEq + +inductive Unop_numtype where + | _I : Unop_IXX -> Unop_numtype + | _F : Unop_FXX -> Unop_numtype + deriving Inhabited, BEq + +inductive Binop_numtype where + | _I : Binop_IXX -> Binop_numtype + | _F : Binop_FXX -> Binop_numtype + deriving Inhabited, BEq + +inductive Testop_numtype where + | _I : Testop_IXX -> Testop_numtype + | _F : Testop_FXX -> Testop_numtype + deriving Inhabited, BEq + +inductive Relop_numtype where + | _I : Relop_IXX -> Relop_numtype + | _F : Relop_FXX -> Relop_numtype + deriving Inhabited, BEq + +inductive Cvtop where + | CONVERT : Cvtop + | REINTERPRET : Cvtop + deriving Inhabited, BEq + +@[reducible] def C_numtype := Nat + +@[reducible] def C_vectype := Nat + +@[reducible] def Blocktype := Functype + + + +inductive Instr where + | UNREACHABLE : Instr + | NOP : Instr + | DROP : Instr + | SELECT : (Option Valtype) -> Instr + | BLOCK : (Blocktype × (List Instr)) -> Instr + | LOOP : (Blocktype × (List Instr)) -> Instr + | IF : (Blocktype × (List Instr) × (List Instr)) -> Instr + | BR : Labelidx -> Instr + | BR_IF : Labelidx -> Instr + | BR_TABLE : ((List Labelidx) × Labelidx) -> Instr + | CALL : Funcidx -> Instr + | CALL_INDIRECT : (Tableidx × Functype) -> Instr + | RETURN : Instr + | CONST : (Numtype × C_numtype) -> Instr + | UNOP : (Numtype × Unop_numtype) -> Instr + | BINOP : (Numtype × Binop_numtype) -> Instr + | TESTOP : (Numtype × Testop_numtype) -> Instr + | RELOP : (Numtype × Relop_numtype) -> Instr + | EXTEND : (Numtype × N) -> Instr + | CVTOP : (Numtype × Cvtop × Numtype × (Option Sx)) -> Instr + | REF_NULL : Reftype -> Instr + | REF_FUNC : Funcidx -> Instr + | REF_IS_NULL : Instr + | LOCAL_GET : Localidx -> Instr + | LOCAL_SET : Localidx -> Instr + | LOCAL_TEE : Localidx -> Instr + | GLOBAL_GET : Globalidx -> Instr + | GLOBAL_SET : Globalidx -> Instr + | TABLE_GET : Tableidx -> Instr + | TABLE_SET : Tableidx -> Instr + | TABLE_SIZE : Tableidx -> Instr + | TABLE_GROW : Tableidx -> Instr + | TABLE_FILL : Tableidx -> Instr + | TABLE_COPY : (Tableidx × Tableidx) -> Instr + | TABLE_INIT : (Tableidx × Elemidx) -> Instr + | ELEM_DROP : Elemidx -> Instr + | MEMORY_SIZE : Instr + | MEMORY_GROW : Instr + | MEMORY_FILL : Instr + | MEMORY_COPY : Instr + | MEMORY_INIT : Dataidx -> Instr + | DATA_DROP : Dataidx -> Instr + | LOAD : (Numtype × (Option (N × Sx)) × U32 × U32) -> Instr + | STORE : (Numtype × (Option N) × U32 × U32) -> Instr + deriving Inhabited, BEq + + + + + + + + + +@[reducible] def Expr := (List Instr) + + + + + +inductive Elemmode where + | TABLE : (Tableidx × Expr) -> Elemmode + | DECLARE : Elemmode + deriving Inhabited, BEq + +inductive Datamode where + | MEMORY : (Memidx × Expr) -> Datamode + deriving Inhabited, BEq + +@[reducible] def Func := /- mixop: `FUNC%%*%` -/ (Functype × (List Valtype) × Expr) + + + +@[reducible] def Global := /- mixop: GLOBAL -/ (Globaltype × Expr) + + + +@[reducible] def Table := /- mixop: TABLE -/ Tabletype + + + +@[reducible] def Mem := /- mixop: MEMORY -/ Memtype + + + +@[reducible] def Elem := /- mixop: `ELEM%%*%?` -/ (Reftype × (List Expr) × (Option Elemmode)) + + + +@[reducible] def Data := /- mixop: `DATA(*)%*%?` -/ ((List (List Byte)) × (Option Datamode)) + + + +@[reducible] def Start := /- mixop: START -/ Funcidx + + + +inductive Externuse where + | FUNC : Funcidx -> Externuse + | GLOBAL : Globalidx -> Externuse + | TABLE : Tableidx -> Externuse + | MEM : Memidx -> Externuse + deriving Inhabited, BEq + + + +@[reducible] def Export := /- mixop: EXPORT -/ (Name × Externuse) + + + +@[reducible] def Import := /- mixop: IMPORT -/ (Name × Name × Externtype) + + + +@[reducible] def Module := /- mixop: `MODULE%*%*%*%*%*%*%*%?%*` -/ ((List Import) × (List Func) × (List Global) × (List Table) × (List Mem) × (List Elem) × (List Data) × (Option Start) × (List Export)) + + + +def «$Ki» : Unit -> Nat + | () => 1024 + +def «$min» : (Nat × Nat) -> Nat + | (0, j) => 0 + | (i, 0) => 0 + | ((i + 1), (j + 1)) => («$min» (i, j)) + +def «$size» : Valtype -> (Option Nat) + | Valtype.I32 => (some 32) + | Valtype.I64 => (some 64) + | Valtype.F32 => (some 32) + | Valtype.F64 => (some 64) + | Valtype.V128 => (some 128) + | x => none + + + +def «$test_sub_ATOM_22» : N -> Nat + | n_3_ATOM_y => 0 + +def «$curried_» : (N × N) -> Nat + | (n_1, n_2) => (n_1 + n_2) + +inductive Testfuse where + | AB_ : (Nat × Nat × Nat) -> Testfuse + | CD : (Nat × Nat × Nat) -> Testfuse + | EF : (Nat × Nat × Nat) -> Testfuse + | GH : (Nat × Nat × Nat) -> Testfuse + | IJ : (Nat × Nat × Nat) -> Testfuse + | KL : (Nat × Nat × Nat) -> Testfuse + | MN : (Nat × Nat × Nat) -> Testfuse + | OP : (Nat × Nat × Nat) -> Testfuse + | QR : (Nat × Nat × Nat) -> Testfuse + deriving Inhabited, BEq + +structure Context where + FUNC : (List Functype) + GLOBAL : (List Globaltype) + TABLE : (List Tabletype) + MEM : (List Memtype) + ELEM : (List Elemtype) + DATA : (List Datatype) + LOCAL : (List Valtype) + LABEL : (List Resulttype) + RETURN : (Option Resulttype) + deriving Inhabited, BEq +instance : Append Context where + append := fun r1 r2 => { + FUNC := r1.FUNC ++ r2.FUNC, + GLOBAL := r1.GLOBAL ++ r2.GLOBAL, + TABLE := r1.TABLE ++ r2.TABLE, + MEM := r1.MEM ++ r2.MEM, + ELEM := r1.ELEM ++ r2.ELEM, + DATA := r1.DATA ++ r2.DATA, + LOCAL := r1.LOCAL ++ r2.LOCAL, + LABEL := r1.LABEL ++ r2.LABEL, + RETURN := r1.RETURN ++ r2.RETURN, + } + + + +inductive Limits_ok : (Limits × Nat) -> Prop where + | rule_0 (k : Nat) (n_1 : N) (n_2 : N) : + ((n_1 <= n_2) && (n_2 <= k)) -> + (Limits_ok ((n_1, n_2), k)) + + + +inductive Functype_ok : Functype -> Prop where + | rule_0 (ft : Functype) : + (Functype_ok ft) + + + +inductive Globaltype_ok : Globaltype -> Prop where + | rule_0 (gt : Globaltype) : + (Globaltype_ok gt) + + + +inductive Tabletype_ok : Tabletype -> Prop where + | rule_0 (lim : Limits) (rt : Reftype) : + (Limits_ok (lim, ((((Nat.pow 2) 32)) - 1))) -> + (Tabletype_ok (lim, rt)) + + + +inductive Memtype_ok : Memtype -> Prop where + | rule_0 (lim : Limits) : + (Limits_ok (lim, (((Nat.pow 2) 16)))) -> + (Memtype_ok lim) + + + +inductive Externtype_ok : Externtype -> Prop where + | func (functype : Functype) : + (Functype_ok functype) -> + (Externtype_ok (Externtype.FUNC functype)) + | «global» (globaltype : Globaltype) : + (Globaltype_ok globaltype) -> + (Externtype_ok (Externtype.GLOBAL globaltype)) + | table (tabletype : Tabletype) : + (Tabletype_ok tabletype) -> + (Externtype_ok (Externtype.TABLE tabletype)) + | mem (memtype : Memtype) : + (Memtype_ok memtype) -> + (Externtype_ok (Externtype.MEM memtype)) + + + +inductive Valtype_sub : (Valtype × Valtype) -> Prop where + | refl (t : Valtype) : + (Valtype_sub (t, t)) + | bot (t : Valtype) : + (Valtype_sub (Valtype.BOT, t)) + + + +inductive Resulttype_sub : ((List Valtype) × (List Valtype)) -> Prop where + | rule_0 (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (t_1.length == t_2.length) -> + (Forall₂ (λ t_1 t_2 ↦ (Valtype_sub (t_1, t_2))) t_1 t_2) -> + (Resulttype_sub (t_1, t_2)) + + + +inductive Limits_sub : (Limits × Limits) -> Prop where + | rule_0 (n_11 : N) (n_12 : N) (n_21 : N) (n_22 : N) : + (n_11 >= n_21) -> + (n_12 <= n_22) -> + (Limits_sub ((n_11, n_12), (n_21, n_22))) + + + +inductive Functype_sub : (Functype × Functype) -> Prop where + | rule_0 (ft : Functype) : + (Functype_sub (ft, ft)) + + + +inductive Globaltype_sub : (Globaltype × Globaltype) -> Prop where + | rule_0 (gt : Globaltype) : + (Globaltype_sub (gt, gt)) + + + +inductive Tabletype_sub : (Tabletype × Tabletype) -> Prop where + | rule_0 (lim_1 : Limits) (lim_2 : Limits) (rt : Reftype) : + (Limits_sub (lim_1, lim_2)) -> + (Tabletype_sub ((lim_1, rt), (lim_2, rt))) + + + +inductive Memtype_sub : (Memtype × Memtype) -> Prop where + | rule_0 (lim_1 : Limits) (lim_2 : Limits) : + (Limits_sub (lim_1, lim_2)) -> + (Memtype_sub (lim_1, lim_2)) + + + +inductive Externtype_sub : (Externtype × Externtype) -> Prop where + | func (ft_1 : Functype) (ft_2 : Functype) : + (Functype_sub (ft_1, ft_2)) -> + (Externtype_sub ((Externtype.FUNC ft_1), (Externtype.FUNC ft_2))) + | «global» (gt_1 : Globaltype) (gt_2 : Globaltype) : + (Globaltype_sub (gt_1, gt_2)) -> + (Externtype_sub ((Externtype.GLOBAL gt_1), (Externtype.GLOBAL gt_2))) + | table (tt_1 : Tabletype) (tt_2 : Tabletype) : + (Tabletype_sub (tt_1, tt_2)) -> + (Externtype_sub ((Externtype.TABLE tt_1), (Externtype.TABLE tt_2))) + | mem (mt_1 : Memtype) (mt_2 : Memtype) : + (Memtype_sub (mt_1, mt_2)) -> + (Externtype_sub ((Externtype.MEM mt_1), (Externtype.MEM mt_2))) + + + +inductive Blocktype_ok : (Context × Blocktype × Functype) -> Prop where + | rule_0 (C : Context) (ft : Functype) : + (Functype_ok ft) -> + (Blocktype_ok (C, ft, ft)) + +mutual +inductive Instr_ok : (Context × Instr × Functype) -> Prop where + | unreachable (C : Context) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (Instr_ok (C, Instr.UNREACHABLE, (t_1, t_2))) + | nop (C : Context) : + (Instr_ok (C, Instr.NOP, ([], []))) + | drop (C : Context) (t : Valtype) : + (Instr_ok (C, Instr.DROP, ([t], []))) + | select_expl (C : Context) (t : Valtype) : + (Instr_ok (C, (Instr.SELECT (some t)), ([t, t, Valtype.I32], [t]))) + | select_impl (C : Context) (numtype : Numtype) (t : Valtype) (t' : Valtype) (vectype : Vectype) : + (Valtype_sub (t, t')) -> + ((t' == («$valtype_numtype» numtype)) || (t' == («$valtype_vectype» vectype))) -> + (Instr_ok (C, (Instr.SELECT none), ([t, t, Valtype.I32], [t]))) + | block (C : Context) (bt : Blocktype) (instr : (List Instr)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (Blocktype_ok (C, bt, (t_1, t_2))) -> + (InstrSeq_ok (({FUNC := [], GLOBAL := [], TABLE := [], MEM := [], ELEM := [], DATA := [], LOCAL := [], LABEL := (List.map (λ t_2 ↦ [t_2]) t_2), RETURN := none} ++ C), instr, (t_1, t_2))) -> + (Instr_ok (C, (Instr.BLOCK (bt, instr)), (t_1, t_2))) + | loop (C : Context) (bt : Blocktype) (instr : (List Instr)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (Blocktype_ok (C, bt, (t_1, t_2))) -> + (InstrSeq_ok (({FUNC := [], GLOBAL := [], TABLE := [], MEM := [], ELEM := [], DATA := [], LOCAL := [], LABEL := (List.map (λ t_1 ↦ [t_1]) t_1), RETURN := none} ++ C), instr, (t_1, t_2))) -> + (Instr_ok (C, (Instr.LOOP (bt, instr)), (t_1, t_2))) + | if (C : Context) (bt : Blocktype) (instr_1 : (List Instr)) (instr_2 : (List Instr)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (Blocktype_ok (C, bt, (t_1, t_2))) -> + (InstrSeq_ok (({FUNC := [], GLOBAL := [], TABLE := [], MEM := [], ELEM := [], DATA := [], LOCAL := [], LABEL := (List.map (λ t_2 ↦ [t_2]) t_2), RETURN := none} ++ C), instr_1, (t_1, t_2))) -> + (InstrSeq_ok (({FUNC := [], GLOBAL := [], TABLE := [], MEM := [], ELEM := [], DATA := [], LOCAL := [], LABEL := (List.map (λ t_2 ↦ [t_2]) t_2), RETURN := none} ++ C), instr_2, (t_1, t_2))) -> + (Instr_ok (C, (Instr.IF (bt, instr_1, instr_2)), (t_1, t_2))) + | br (C : Context) (l : Labelidx) (t : (List Valtype)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (l < C.LABEL.length) -> + ((C.LABEL.get! l) == t) -> + (Instr_ok (C, (Instr.BR l), ((t_1 ++ t), t_2))) + | br_if (C : Context) (l : Labelidx) (t : (List Valtype)) : + (l < C.LABEL.length) -> + ((C.LABEL.get! l) == t) -> + (Instr_ok (C, (Instr.BR_IF l), ((t ++ [Valtype.I32]), t))) + | br_table (C : Context) (l : (List Labelidx)) (l' : Labelidx) (t : (List Valtype)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (Forall (λ l ↦ (l < C.LABEL.length)) l) -> + (l' < C.LABEL.length) -> + (Forall (λ l ↦ (Resulttype_sub (t, (C.LABEL.get! l)))) l) -> + (Resulttype_sub (t, (C.LABEL.get! l'))) -> + (Instr_ok (C, (Instr.BR_TABLE (l, l')), ((t_1 ++ t), t_2))) + | return (C : Context) (t : (List Valtype)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (C.RETURN == (some t)) -> + (Instr_ok (C, Instr.RETURN, ((t_1 ++ t), t_2))) + | call (C : Context) (t_1 : (List Valtype)) (t_2 : (List Valtype)) (x : Idx) : + (x < C.FUNC.length) -> + ((C.FUNC.get! x) == (t_1, t_2)) -> + (Instr_ok (C, (Instr.CALL x), (t_1, t_2))) + | call_indirect (C : Context) (ft : Functype) (lim : Limits) (t_1 : (List Valtype)) (t_2 : (List Valtype)) (x : Idx) : + (x < C.TABLE.length) -> + ((C.TABLE.get! x) == (lim, Reftype.FUNCREF)) -> + (ft == (t_1, t_2)) -> + (Instr_ok (C, (Instr.CALL_INDIRECT (x, ft)), ((t_1 ++ [Valtype.I32]), t_2))) + | const (C : Context) (c_nt : C_numtype) (nt : Numtype) : + (Instr_ok (C, (Instr.CONST (nt, c_nt)), ([], [(«$valtype_numtype» nt)]))) + | unop (C : Context) (nt : Numtype) (unop : Unop_numtype) : + (Instr_ok (C, (Instr.UNOP (nt, unop)), ([(«$valtype_numtype» nt)], [(«$valtype_numtype» nt)]))) + | binop (C : Context) (binop : Binop_numtype) (nt : Numtype) : + (Instr_ok (C, (Instr.BINOP (nt, binop)), ([(«$valtype_numtype» nt), («$valtype_numtype» nt)], [(«$valtype_numtype» nt)]))) + | testop (C : Context) (nt : Numtype) (testop : Testop_numtype) : + (Instr_ok (C, (Instr.TESTOP (nt, testop)), ([(«$valtype_numtype» nt)], [Valtype.I32]))) + | relop (C : Context) (nt : Numtype) (relop : Relop_numtype) : + (Instr_ok (C, (Instr.RELOP (nt, relop)), ([(«$valtype_numtype» nt), («$valtype_numtype» nt)], [Valtype.I32]))) + | extend (C : Context) (n : N) (nt : Numtype) (o0 : Nat) : + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + (n <= o0) -> + (Instr_ok (C, (Instr.EXTEND (nt, n)), ([(«$valtype_numtype» nt)], [(«$valtype_numtype» nt)]))) + | reinterpret (C : Context) (nt_1 : Numtype) (nt_2 : Numtype) (o0 : Nat) (o1 : Nat) : + ((«$size» («$valtype_numtype» nt_1)) == (some o0)) -> + ((«$size» («$valtype_numtype» nt_2)) == (some o1)) -> + (nt_1 != nt_2) -> + (o0 == o1) -> + (Instr_ok (C, (Instr.CVTOP (nt_1, Cvtop.REINTERPRET, nt_2, none)), ([(«$valtype_numtype» nt_2)], [(«$valtype_numtype» nt_1)]))) + | convert_i (C : Context) (in_1 : In) (in_2 : In) (sx : (Option Sx)) (o0 : Nat) (o1 : Nat) : + ((«$size» («$valtype_in» in_1)) == (some o0)) -> + ((«$size» («$valtype_in» in_2)) == (some o1)) -> + (in_1 != in_2) -> + ((sx == none) = (o0 > o1)) -> + (Instr_ok (C, (Instr.CVTOP ((«$numtype_in» in_1), Cvtop.CONVERT, («$numtype_in» in_2), sx)), ([(«$valtype_in» in_2)], [(«$valtype_in» in_1)]))) + | convert_f (C : Context) (fn_1 : Fn) (fn_2 : Fn) : + (fn_1 != fn_2) -> + (Instr_ok (C, (Instr.CVTOP ((«$numtype_fn» fn_1), Cvtop.CONVERT, («$numtype_fn» fn_2), none)), ([(«$valtype_fn» fn_2)], [(«$valtype_fn» fn_1)]))) + | ref_null (C : Context) (rt : Reftype) : + (Instr_ok (C, (Instr.REF_NULL rt), ([], [(«$valtype_reftype» rt)]))) + | ref_func (C : Context) (ft : Functype) (x : Idx) : + (x < C.FUNC.length) -> + ((C.FUNC.get! x) == ft) -> + (Instr_ok (C, (Instr.REF_FUNC x), ([], [Valtype.FUNCREF]))) + | ref_is_null (C : Context) (rt : Reftype) : + (Instr_ok (C, Instr.REF_IS_NULL, ([(«$valtype_reftype» rt)], [Valtype.I32]))) + | local_get (C : Context) (t : Valtype) (x : Idx) : + (x < C.LOCAL.length) -> + ((C.LOCAL.get! x) == t) -> + (Instr_ok (C, (Instr.LOCAL_GET x), ([], [t]))) + | local_set (C : Context) (t : Valtype) (x : Idx) : + (x < C.LOCAL.length) -> + ((C.LOCAL.get! x) == t) -> + (Instr_ok (C, (Instr.LOCAL_SET x), ([t], []))) + | local_tee (C : Context) (t : Valtype) (x : Idx) : + (x < C.LOCAL.length) -> + ((C.LOCAL.get! x) == t) -> + (Instr_ok (C, (Instr.LOCAL_TEE x), ([t], [t]))) + | global_get (C : Context) (t : Valtype) (x : Idx) (w0 : (Option Unit)) : + (x < C.GLOBAL.length) -> + ((C.GLOBAL.get! x) == (w0, t)) -> + (Instr_ok (C, (Instr.GLOBAL_GET x), ([], [t]))) + | global_set (C : Context) (t : Valtype) (x : Idx) : + (x < C.GLOBAL.length) -> + ((C.GLOBAL.get! x) == ((some ()), t)) -> + (Instr_ok (C, (Instr.GLOBAL_SET x), ([t], []))) + | table_get (C : Context) (lim : Limits) (rt : Reftype) (x : Idx) : + (x < C.TABLE.length) -> + ((C.TABLE.get! x) == (lim, rt)) -> + (Instr_ok (C, (Instr.TABLE_GET x), ([Valtype.I32], [(«$valtype_reftype» rt)]))) + | table_set (C : Context) (lim : Limits) (rt : Reftype) (x : Idx) : + (x < C.TABLE.length) -> + ((C.TABLE.get! x) == (lim, rt)) -> + (Instr_ok (C, (Instr.TABLE_SET x), ([Valtype.I32, («$valtype_reftype» rt)], []))) + | table_size (C : Context) (tt : Tabletype) (x : Idx) : + (x < C.TABLE.length) -> + ((C.TABLE.get! x) == tt) -> + (Instr_ok (C, (Instr.TABLE_SIZE x), ([], [Valtype.I32]))) + | table_grow (C : Context) (lim : Limits) (rt : Reftype) (x : Idx) : + (x < C.TABLE.length) -> + ((C.TABLE.get! x) == (lim, rt)) -> + (Instr_ok (C, (Instr.TABLE_GROW x), ([(«$valtype_reftype» rt), Valtype.I32], [Valtype.I32]))) + | table_fill (C : Context) (lim : Limits) (rt : Reftype) (x : Idx) : + (x < C.TABLE.length) -> + ((C.TABLE.get! x) == (lim, rt)) -> + (Instr_ok (C, (Instr.TABLE_FILL x), ([Valtype.I32, («$valtype_reftype» rt), Valtype.I32], []))) + | table_copy (C : Context) (lim_1 : Limits) (lim_2 : Limits) (rt : Reftype) (x_1 : Idx) (x_2 : Idx) : + (x_1 < C.TABLE.length) -> + (x_2 < C.TABLE.length) -> + ((C.TABLE.get! x_1) == (lim_1, rt)) -> + ((C.TABLE.get! x_2) == (lim_2, rt)) -> + (Instr_ok (C, (Instr.TABLE_COPY (x_1, x_2)), ([Valtype.I32, Valtype.I32, Valtype.I32], []))) + | table_init (C : Context) (lim : Limits) (rt : Reftype) (x_1 : Idx) (x_2 : Idx) : + (x_1 < C.TABLE.length) -> + (x_2 < C.ELEM.length) -> + ((C.TABLE.get! x_1) == (lim, rt)) -> + ((C.ELEM.get! x_2) == rt) -> + (Instr_ok (C, (Instr.TABLE_INIT (x_1, x_2)), ([Valtype.I32, Valtype.I32, Valtype.I32], []))) + | elem_drop (C : Context) (rt : Reftype) (x : Idx) : + (x < C.ELEM.length) -> + ((C.ELEM.get! x) == rt) -> + (Instr_ok (C, (Instr.ELEM_DROP x), ([], []))) + | memory_size (C : Context) (mt : Memtype) : + (0 < C.MEM.length) -> + ((C.MEM.get! 0) == mt) -> + (Instr_ok (C, Instr.MEMORY_SIZE, ([], [Valtype.I32]))) + | memory_grow (C : Context) (mt : Memtype) : + (0 < C.MEM.length) -> + ((C.MEM.get! 0) == mt) -> + (Instr_ok (C, Instr.MEMORY_GROW, ([Valtype.I32], [Valtype.I32]))) + | memory_fill (C : Context) (mt : Memtype) : + (0 < C.MEM.length) -> + ((C.MEM.get! 0) == mt) -> + (Instr_ok (C, Instr.MEMORY_FILL, ([Valtype.I32, Valtype.I32, Valtype.I32], [Valtype.I32]))) + | memory_copy (C : Context) (mt : Memtype) : + (0 < C.MEM.length) -> + ((C.MEM.get! 0) == mt) -> + (Instr_ok (C, Instr.MEMORY_COPY, ([Valtype.I32, Valtype.I32, Valtype.I32], [Valtype.I32]))) + | memory_init (C : Context) (mt : Memtype) (x : Idx) : + (0 < C.MEM.length) -> + (x < C.DATA.length) -> + ((C.MEM.get! 0) == mt) -> + ((C.DATA.get! x) == ()) -> + (Instr_ok (C, (Instr.MEMORY_INIT x), ([Valtype.I32, Valtype.I32, Valtype.I32], [Valtype.I32]))) + | data_drop (C : Context) (x : Idx) : + (x < C.DATA.length) -> + ((C.DATA.get! x) == ()) -> + (Instr_ok (C, (Instr.DATA_DROP x), ([], []))) + | load (C : Context) («in» : In) (mt : Memtype) (n : (Option N)) (n_A : N) (n_O : N) (nt : Numtype) (sx : (Option Sx)) (o0 : Nat) (o1 : (Option Nat)) : + (0 < C.MEM.length) -> + ((n == none) = (o1 == none)) -> + ((n == none) = (sx == none)) -> + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + (Forall (λ o1 ↦ ((«$size» («$valtype_numtype» nt)) == (some o1))) o1.toList) -> + ((C.MEM.get! 0) == mt) -> + ((((Nat.pow 2) n_A)) <= (((Nat.div o0) 8))) -> + (Forall₂ (λ n o1 ↦ (((((Nat.pow 2) n_A)) <= (((Nat.div n) 8))) && ((((Nat.div n) 8)) < (((Nat.div o1) 8))))) n.toList o1.toList) -> + ((n == none) || (nt == («$numtype_in» «in»))) -> + (Instr_ok (C, (Instr.LOAD (nt, (Option.zipWith (λ n sx ↦ (n, sx)) n sx), n_A, n_O)), ([Valtype.I32], [(«$valtype_numtype» nt)]))) + | store (C : Context) («in» : In) (mt : Memtype) (n : (Option N)) (n_A : N) (n_O : N) (nt : Numtype) (o0 : Nat) (o1 : (Option Nat)) : + (0 < C.MEM.length) -> + ((n == none) = (o1 == none)) -> + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + (Forall (λ o1 ↦ ((«$size» («$valtype_numtype» nt)) == (some o1))) o1.toList) -> + ((C.MEM.get! 0) == mt) -> + ((((Nat.pow 2) n_A)) <= (((Nat.div o0) 8))) -> + (Forall₂ (λ n o1 ↦ (((((Nat.pow 2) n_A)) <= (((Nat.div n) 8))) && ((((Nat.div n) 8)) < (((Nat.div o1) 8))))) n.toList o1.toList) -> + ((n == none) || (nt == («$numtype_in» «in»))) -> + (Instr_ok (C, (Instr.STORE (nt, n, n_A, n_O)), ([Valtype.I32, («$valtype_numtype» nt)], []))) +inductive InstrSeq_ok : (Context × (List Instr) × Functype) -> Prop where + | empty (C : Context) : + (InstrSeq_ok (C, [], ([], []))) + | seq (C : Context) (instr_1 : Instr) (instr_2 : Instr) (t_1 : (List Valtype)) (t_2 : (List Valtype)) (t_3 : (List Valtype)) : + (Instr_ok (C, instr_1, (t_1, t_2))) -> + (InstrSeq_ok (C, [instr_2], (t_2, t_3))) -> + (InstrSeq_ok (C, ([instr_1] ++ [instr_2]), (t_1, t_3))) + | weak (C : Context) (instr : (List Instr)) (t'_1 : (List Valtype)) (t'_2 : (List Valtype)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (InstrSeq_ok (C, instr, (t_1, t_2))) -> + (Resulttype_sub (t'_1, t_1)) -> + (Resulttype_sub (t_2, t'_2)) -> + (InstrSeq_ok (C, instr, (t'_1, t'_2))) + | frame (C : Context) (instr : (List Instr)) (t : (List Valtype)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (InstrSeq_ok (C, instr, (t_1, t_2))) -> + (InstrSeq_ok (C, instr, ((t ++ t_1), (t ++ t_2))))end + + + + + +inductive Expr_ok : (Context × Expr × Resulttype) -> Prop where + | rule_0 (C : Context) (instr : (List Instr)) (t : (List Valtype)) : + (InstrSeq_ok (C, instr, ([], t))) -> + (Expr_ok (C, instr, t)) + + + + + +inductive Instr_const : (Context × Instr) -> Prop where + | const (C : Context) (c : C_numtype) (nt : Numtype) : + (Instr_const (C, (Instr.CONST (nt, c)))) + | ref_null (C : Context) (rt : Reftype) : + (Instr_const (C, (Instr.REF_NULL rt))) + | ref_func (C : Context) (x : Idx) : + (Instr_const (C, (Instr.REF_FUNC x))) + | global_get (C : Context) (t : Valtype) (x : Idx) : + (x < C.GLOBAL.length) -> + ((C.GLOBAL.get! x) == (none, t)) -> + (Instr_const (C, (Instr.GLOBAL_GET x))) + + + +inductive Expr_const : (Context × Expr) -> Prop where + | rule_0 (C : Context) (instr : (List Instr)) : + (Forall (λ instr ↦ (Instr_const (C, instr))) instr) -> + (Expr_const (C, instr)) + + + +inductive Expr_ok_const : (Context × Expr × Valtype) -> Prop where + | rule_0 (C : Context) (expr : Expr) (t : Valtype) : + (Expr_ok (C, expr, [t])) -> + (Expr_const (C, expr)) -> + (Expr_ok_const (C, expr, t)) + + + +inductive Func_ok : (Context × Func × Functype) -> Prop where + | rule_0 (C : Context) (expr : Expr) (ft : Functype) (t : (List Valtype)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) : + (ft == (t_1, t_2)) -> + (Functype_ok ft) -> + (Expr_ok (({FUNC := [], GLOBAL := [], TABLE := [], MEM := [], ELEM := [], DATA := [], LOCAL := [], LABEL := [], RETURN := (some t_2)} ++ ({FUNC := [], GLOBAL := [], TABLE := [], MEM := [], ELEM := [], DATA := [], LOCAL := [], LABEL := [t_2], RETURN := none} ++ ({FUNC := [], GLOBAL := [], TABLE := [], MEM := [], ELEM := [], DATA := [], LOCAL := (t_1 ++ t), LABEL := [], RETURN := none} ++ C))), expr, t_2)) -> + (Func_ok (C, (ft, t, expr), ft)) + + + +inductive Global_ok : (Context × Global × Globaltype) -> Prop where + | rule_0 (C : Context) (expr : Expr) (gt : Globaltype) (t : Valtype) (w0 : (Option Unit)) : + (Globaltype_ok gt) -> + (gt == (w0, t)) -> + (Expr_ok_const (C, expr, t)) -> + (Global_ok (C, (gt, expr), gt)) + + + +inductive Table_ok : (Context × Table × Tabletype) -> Prop where + | rule_0 (C : Context) (tt : Tabletype) : + (Tabletype_ok tt) -> + (Table_ok (C, tt, tt)) + + + +inductive Mem_ok : (Context × Mem × Memtype) -> Prop where + | rule_0 (C : Context) (mt : Memtype) : + (Memtype_ok mt) -> + (Mem_ok (C, mt, mt)) + + + +inductive Elemmode_ok : (Context × Elemmode × Reftype) -> Prop where + | active (C : Context) (expr : Expr) (lim : Limits) (rt : Reftype) (x : Idx) : + (x < C.TABLE.length) -> + ((C.TABLE.get! x) == (lim, rt)) -> + (Expr_ok_const (C, expr, Valtype.I32)) /- *{} -/ -> + (Elemmode_ok (C, (Elemmode.TABLE (x, expr)), rt)) + | declare (C : Context) (rt : Reftype) : + (Elemmode_ok (C, Elemmode.DECLARE, rt)) + +inductive Elem_ok : (Context × Elem × Reftype) -> Prop where + | rule_0 (C : Context) (elemmode : (Option Elemmode)) (expr : (List Expr)) (rt : Reftype) : + (Forall (λ expr ↦ (Expr_ok (C, expr, [(«$valtype_reftype» rt)]))) expr) -> + (Forall (λ elemmode ↦ (Elemmode_ok (C, elemmode, rt))) elemmode.toList) -> + (Elem_ok (C, (rt, expr, elemmode), rt)) + + + +inductive Datamode_ok : (Context × Datamode) -> Prop where + | rule_0 (C : Context) (expr : Expr) (mt : Memtype) : + (0 < C.MEM.length) -> + ((C.MEM.get! 0) == mt) -> + (Expr_ok_const (C, expr, Valtype.I32)) /- *{} -/ -> + (Datamode_ok (C, (Datamode.MEMORY (0, expr)))) + +inductive Data_ok : (Context × Data) -> Prop where + | rule_0 (C : Context) (b : (List (List Byte))) (datamode : (Option Datamode)) : + (Forall (λ datamode ↦ (Datamode_ok (C, datamode))) datamode.toList) -> + (Data_ok (C, ((List.map (λ b ↦ b) b), datamode))) + + + + + + + +inductive Start_ok : (Context × Start) -> Prop where + | rule_0 (C : Context) (x : Idx) : + (x < C.FUNC.length) -> + ((C.FUNC.get! x) == ([], [])) -> + (Start_ok (C, x)) + + + +inductive Import_ok : (Context × Import × Externtype) -> Prop where + | rule_0 (C : Context) (name_1 : Name) (name_2 : Name) (xt : Externtype) : + (Externtype_ok xt) -> + (Import_ok (C, (name_1, name_2, xt), xt)) + + + +inductive Externuse_ok : (Context × Externuse × Externtype) -> Prop where + | func (C : Context) (ft : Functype) (x : Idx) : + (x < C.FUNC.length) -> + ((C.FUNC.get! x) == ft) -> + (Externuse_ok (C, (Externuse.FUNC x), (Externtype.FUNC ft))) + | «global» (C : Context) (gt : Globaltype) (x : Idx) : + (x < C.GLOBAL.length) -> + ((C.GLOBAL.get! x) == gt) -> + (Externuse_ok (C, (Externuse.GLOBAL x), (Externtype.GLOBAL gt))) + | table (C : Context) (tt : Tabletype) (x : Idx) : + (x < C.TABLE.length) -> + ((C.TABLE.get! x) == tt) -> + (Externuse_ok (C, (Externuse.TABLE x), (Externtype.TABLE tt))) + | mem (C : Context) (mt : Memtype) (x : Idx) : + (x < C.MEM.length) -> + ((C.MEM.get! x) == mt) -> + (Externuse_ok (C, (Externuse.MEM x), (Externtype.MEM mt))) + +inductive Export_ok : (Context × Export × Externtype) -> Prop where + | rule_0 (C : Context) (externuse : Externuse) (name : Name) (xt : Externtype) : + (Externuse_ok (C, externuse, xt)) -> + (Export_ok (C, (name, externuse), xt)) + + + + + +inductive Module_ok : Module -> Prop where + | rule_0 (C : Context) (data : (List Data)) (elem : (List Elem)) («export» : (List Export)) (ft : (List Functype)) (func : (List Func)) («global» : (List Global)) (gt : (List Globaltype)) («import» : (List Import)) (mem : (List Mem)) (mt : (List Memtype)) (n : N) (rt : (List Reftype)) (start : (Option Start)) (table : (List Table)) (tt : (List Tabletype)) : + (ft.length == func.length) -> + («global».length == gt.length) -> + (table.length == tt.length) -> + (mem.length == mt.length) -> + (elem.length == rt.length) -> + (C == {FUNC := ft, GLOBAL := gt, TABLE := tt, MEM := mt, ELEM := rt, DATA := [()], LOCAL := [], LABEL := [], RETURN := none}) -> + (Forall₂ (λ ft func ↦ (Func_ok (C, func, ft))) ft func) -> + (Forall₂ (λ «global» gt ↦ (Global_ok (C, «global», gt))) «global» gt) -> + (Forall₂ (λ table tt ↦ (Table_ok (C, table, tt))) table tt) -> + (Forall₂ (λ mem mt ↦ (Mem_ok (C, mem, mt))) mem mt) -> + (Forall₂ (λ elem rt ↦ (Elem_ok (C, elem, rt))) elem rt) -> + (Forall (λ data ↦ (Data_ok (C, data))) data) -> + (Forall (λ start ↦ (Start_ok (C, start))) start.toList) -> + (mem.length <= 1) -> + (Module_ok («import», func, «global», table, mem, elem, data, start, «export»)) + + + +@[reducible] def Addr := Nat + + + +@[reducible] def Funcaddr := Addr + + + +@[reducible] def Globaladdr := Addr + + + +@[reducible] def Tableaddr := Addr + + + +@[reducible] def Memaddr := Addr + + + +@[reducible] def Elemaddr := Addr + + + +@[reducible] def Dataaddr := Addr + + + +@[reducible] def Labeladdr := Addr + + + +@[reducible] def Hostaddr := Addr + + + +inductive Num where + | CONST : (Numtype × C_numtype) -> Num + deriving Inhabited, BEq + + + +inductive Ref where + | REF_NULL : Reftype -> Ref + | REF_FUNC_ADDR : Funcaddr -> Ref + | REF_HOST_ADDR : Hostaddr -> Ref + deriving Inhabited, BEq + + + +inductive Val where + | CONST : (Numtype × C_numtype) -> Val + | REF_NULL : Reftype -> Val + | REF_FUNC_ADDR : Funcaddr -> Val + | REF_HOST_ADDR : Hostaddr -> Val + deriving Inhabited, BEq + + + +inductive Result where + | _VALS : (List Val) -> Result + | TRAP : Result + deriving Inhabited, BEq + + + +inductive Externval where + | FUNC : Funcaddr -> Externval + | GLOBAL : Globaladdr -> Externval + | TABLE : Tableaddr -> Externval + | MEM : Memaddr -> Externval + deriving Inhabited, BEq + + + +def «$default_» : Valtype -> (Option Val) + | Valtype.I32 => (some (Val.CONST (Numtype.I32, 0))) + | Valtype.I64 => (some (Val.CONST (Numtype.I64, 0))) + | Valtype.F32 => (some (Val.CONST (Numtype.F32, 0))) + | Valtype.F64 => (some (Val.CONST (Numtype.F64, 0))) + | Valtype.FUNCREF => (some (Val.REF_NULL Reftype.FUNCREF)) + | Valtype.EXTERNREF => (some (Val.REF_NULL Reftype.EXTERNREF)) + | x => none + + + +@[reducible] def Exportinst := /- mixop: EXPORT -/ (Name × Externval) + +structure Moduleinst where + FUNC : (List Funcaddr) + GLOBAL : (List Globaladdr) + TABLE : (List Tableaddr) + MEM : (List Memaddr) + ELEM : (List Elemaddr) + DATA : (List Dataaddr) + EXPORT : (List Exportinst) + deriving Inhabited, BEq +instance : Append Moduleinst where + append := fun r1 r2 => { + FUNC := r1.FUNC ++ r2.FUNC, + GLOBAL := r1.GLOBAL ++ r2.GLOBAL, + TABLE := r1.TABLE ++ r2.TABLE, + MEM := r1.MEM ++ r2.MEM, + ELEM := r1.ELEM ++ r2.ELEM, + DATA := r1.DATA ++ r2.DATA, + EXPORT := r1.EXPORT ++ r2.EXPORT, + } + +@[reducible] def Funcinst := /- mixop: `%;%` -/ (Moduleinst × Func) + + + +@[reducible] def Globalinst := Val + + + +@[reducible] def Tableinst := (List Ref) + + + +@[reducible] def Meminst := (List Byte) + + + +@[reducible] def Eleminst := (List Ref) + + + +@[reducible] def Datainst := (List Byte) + + + + + +structure Store where + FUNC : (List Funcinst) + GLOBAL : (List Globalinst) + TABLE : (List Tableinst) + MEM : (List Meminst) + ELEM : (List Eleminst) + DATA : (List Datainst) + deriving Inhabited, BEq +instance : Append Store where + append := fun r1 r2 => { + FUNC := r1.FUNC ++ r2.FUNC, + GLOBAL := r1.GLOBAL ++ r2.GLOBAL, + TABLE := r1.TABLE ++ r2.TABLE, + MEM := r1.MEM ++ r2.MEM, + ELEM := r1.ELEM ++ r2.ELEM, + DATA := r1.DATA ++ r2.DATA, + } + + + + + +structure Frame where + LOCAL : (List Val) + MODULE : Moduleinst + deriving Inhabited, BEq +instance : Append Frame where + append := fun r1 r2 => { + LOCAL := r1.LOCAL ++ r2.LOCAL, + MODULE := r1.MODULE ++ r2.MODULE, + } + + + +@[reducible] def State := /- mixop: `%;%` -/ (Store × Frame) + + + +inductive Admininstr where + | UNREACHABLE : Admininstr + | NOP : Admininstr + | DROP : Admininstr + | SELECT : (Option Valtype) -> Admininstr + | BLOCK : (Blocktype × (List Instr)) -> Admininstr + | LOOP : (Blocktype × (List Instr)) -> Admininstr + | IF : (Blocktype × (List Instr) × (List Instr)) -> Admininstr + | BR : Labelidx -> Admininstr + | BR_IF : Labelidx -> Admininstr + | BR_TABLE : ((List Labelidx) × Labelidx) -> Admininstr + | CALL : Funcidx -> Admininstr + | CALL_INDIRECT : (Tableidx × Functype) -> Admininstr + | RETURN : Admininstr + | CONST : (Numtype × C_numtype) -> Admininstr + | UNOP : (Numtype × Unop_numtype) -> Admininstr + | BINOP : (Numtype × Binop_numtype) -> Admininstr + | TESTOP : (Numtype × Testop_numtype) -> Admininstr + | RELOP : (Numtype × Relop_numtype) -> Admininstr + | EXTEND : (Numtype × N) -> Admininstr + | CVTOP : (Numtype × Cvtop × Numtype × (Option Sx)) -> Admininstr + | REF_NULL : Reftype -> Admininstr + | REF_FUNC : Funcidx -> Admininstr + | REF_IS_NULL : Admininstr + | LOCAL_GET : Localidx -> Admininstr + | LOCAL_SET : Localidx -> Admininstr + | LOCAL_TEE : Localidx -> Admininstr + | GLOBAL_GET : Globalidx -> Admininstr + | GLOBAL_SET : Globalidx -> Admininstr + | TABLE_GET : Tableidx -> Admininstr + | TABLE_SET : Tableidx -> Admininstr + | TABLE_SIZE : Tableidx -> Admininstr + | TABLE_GROW : Tableidx -> Admininstr + | TABLE_FILL : Tableidx -> Admininstr + | TABLE_COPY : (Tableidx × Tableidx) -> Admininstr + | TABLE_INIT : (Tableidx × Elemidx) -> Admininstr + | ELEM_DROP : Elemidx -> Admininstr + | MEMORY_SIZE : Admininstr + | MEMORY_GROW : Admininstr + | MEMORY_FILL : Admininstr + | MEMORY_COPY : Admininstr + | MEMORY_INIT : Dataidx -> Admininstr + | DATA_DROP : Dataidx -> Admininstr + | LOAD : (Numtype × (Option (N × Sx)) × U32 × U32) -> Admininstr + | STORE : (Numtype × (Option N) × U32 × U32) -> Admininstr + | REF_FUNC_ADDR : Funcaddr -> Admininstr + | REF_HOST_ADDR : Hostaddr -> Admininstr + | CALL_ADDR : Funcaddr -> Admininstr + | LABEL_ : (N × (List Instr) × (List Admininstr)) -> Admininstr + | FRAME_ : (N × Frame × (List Admininstr)) -> Admininstr + | TRAP : Admininstr + deriving Inhabited, BEq + +def «$admininstr_globalinst» : Globalinst -> Admininstr + | (Val.CONST (x0, x1)) => (Admininstr.CONST (x0, x1)) + | (Val.REF_NULL x) => (Admininstr.REF_NULL x) + | (Val.REF_FUNC_ADDR x) => (Admininstr.REF_FUNC_ADDR x) + | (Val.REF_HOST_ADDR x) => (Admininstr.REF_HOST_ADDR x) + +def «$admininstr_instr» : Instr -> Admininstr + | Instr.UNREACHABLE => Admininstr.UNREACHABLE + | Instr.NOP => Admininstr.NOP + | Instr.DROP => Admininstr.DROP + | (Instr.SELECT x) => (Admininstr.SELECT x) + | (Instr.BLOCK (x0, x1)) => (Admininstr.BLOCK (x0, x1)) + | (Instr.LOOP (x0, x1)) => (Admininstr.LOOP (x0, x1)) + | (Instr.IF (x0, x1, x2)) => (Admininstr.IF (x0, x1, x2)) + | (Instr.BR x) => (Admininstr.BR x) + | (Instr.BR_IF x) => (Admininstr.BR_IF x) + | (Instr.BR_TABLE (x0, x1)) => (Admininstr.BR_TABLE (x0, x1)) + | (Instr.CALL x) => (Admininstr.CALL x) + | (Instr.CALL_INDIRECT (x0, x1)) => (Admininstr.CALL_INDIRECT (x0, x1)) + | Instr.RETURN => Admininstr.RETURN + | (Instr.CONST (x0, x1)) => (Admininstr.CONST (x0, x1)) + | (Instr.UNOP (x0, x1)) => (Admininstr.UNOP (x0, x1)) + | (Instr.BINOP (x0, x1)) => (Admininstr.BINOP (x0, x1)) + | (Instr.TESTOP (x0, x1)) => (Admininstr.TESTOP (x0, x1)) + | (Instr.RELOP (x0, x1)) => (Admininstr.RELOP (x0, x1)) + | (Instr.EXTEND (x0, x1)) => (Admininstr.EXTEND (x0, x1)) + | (Instr.CVTOP (x0, x1, x2, x3)) => (Admininstr.CVTOP (x0, x1, x2, x3)) + | (Instr.REF_NULL x) => (Admininstr.REF_NULL x) + | (Instr.REF_FUNC x) => (Admininstr.REF_FUNC x) + | Instr.REF_IS_NULL => Admininstr.REF_IS_NULL + | (Instr.LOCAL_GET x) => (Admininstr.LOCAL_GET x) + | (Instr.LOCAL_SET x) => (Admininstr.LOCAL_SET x) + | (Instr.LOCAL_TEE x) => (Admininstr.LOCAL_TEE x) + | (Instr.GLOBAL_GET x) => (Admininstr.GLOBAL_GET x) + | (Instr.GLOBAL_SET x) => (Admininstr.GLOBAL_SET x) + | (Instr.TABLE_GET x) => (Admininstr.TABLE_GET x) + | (Instr.TABLE_SET x) => (Admininstr.TABLE_SET x) + | (Instr.TABLE_SIZE x) => (Admininstr.TABLE_SIZE x) + | (Instr.TABLE_GROW x) => (Admininstr.TABLE_GROW x) + | (Instr.TABLE_FILL x) => (Admininstr.TABLE_FILL x) + | (Instr.TABLE_COPY (x0, x1)) => (Admininstr.TABLE_COPY (x0, x1)) + | (Instr.TABLE_INIT (x0, x1)) => (Admininstr.TABLE_INIT (x0, x1)) + | (Instr.ELEM_DROP x) => (Admininstr.ELEM_DROP x) + | Instr.MEMORY_SIZE => Admininstr.MEMORY_SIZE + | Instr.MEMORY_GROW => Admininstr.MEMORY_GROW + | Instr.MEMORY_FILL => Admininstr.MEMORY_FILL + | Instr.MEMORY_COPY => Admininstr.MEMORY_COPY + | (Instr.MEMORY_INIT x) => (Admininstr.MEMORY_INIT x) + | (Instr.DATA_DROP x) => (Admininstr.DATA_DROP x) + | (Instr.LOAD (x0, x1, x2, x3)) => (Admininstr.LOAD (x0, x1, x2, x3)) + | (Instr.STORE (x0, x1, x2, x3)) => (Admininstr.STORE (x0, x1, x2, x3)) + +def «$admininstr_ref» : Ref -> Admininstr + | (Ref.REF_NULL x) => (Admininstr.REF_NULL x) + | (Ref.REF_FUNC_ADDR x) => (Admininstr.REF_FUNC_ADDR x) + | (Ref.REF_HOST_ADDR x) => (Admininstr.REF_HOST_ADDR x) + +def «$admininstr_val» : Val -> Admininstr + | (Val.CONST (x0, x1)) => (Admininstr.CONST (x0, x1)) + | (Val.REF_NULL x) => (Admininstr.REF_NULL x) + | (Val.REF_FUNC_ADDR x) => (Admininstr.REF_FUNC_ADDR x) + | (Val.REF_HOST_ADDR x) => (Admininstr.REF_HOST_ADDR x) + +@[reducible] def Config := /- mixop: `%;%*` -/ (State × (List Admininstr)) + + + +def «$funcaddr» : State -> (List Funcaddr) + | (s, f) => f.MODULE.FUNC + + + +def «$funcinst» : State -> (List Funcinst) + | (s, f) => s.FUNC + + + +def «$func» : (State × Funcidx) -> Funcinst + | ((s, f), x) => (s.FUNC.get! (f.MODULE.FUNC.get! x)) + + + +def «$global» : (State × Globalidx) -> Globalinst + | ((s, f), x) => (s.GLOBAL.get! (f.MODULE.GLOBAL.get! x)) + + + +def «$table» : (State × Tableidx) -> Tableinst + | ((s, f), x) => (s.TABLE.get! (f.MODULE.TABLE.get! x)) + + + +def «$mem» : (State × Memidx) -> Meminst + | ((s, f), x) => (s.MEM.get! (f.MODULE.MEM.get! x)) + + + +def «$elem» : (State × Tableidx) -> Eleminst + | ((s, f), x) => (s.ELEM.get! (f.MODULE.ELEM.get! x)) + + + +def «$data» : (State × Dataidx) -> Datainst + | ((s, f), x) => (s.DATA.get! (f.MODULE.DATA.get! x)) + + + +def «$local» : (State × Localidx) -> Val + | ((s, f), x) => (f.LOCAL.get! x) + + + +def «$with_local» : (State × Localidx × Val) -> State + | ((s, f), x, v) => (s, {f with LOCAL := (f.LOCAL.upd x v) }) + + + +def «$with_global» : (State × Globalidx × Val) -> State + | ((s, f), x, v) => ({s with GLOBAL := (s.GLOBAL.upd (f.MODULE.GLOBAL.get! x) v) }, f) + + + +def «$with_table» : (State × Tableidx × Nat × Ref) -> State + | ((s, f), x, i, r) => ({s with TABLE := (s.TABLE.upd (f.MODULE.TABLE.get! x) ((s.TABLE.get! (f.MODULE.TABLE.get! x)).upd i r)) }, f) + + + +def «$with_tableext» : (State × Tableidx × (List Ref)) -> State + | ((s, f), x, r) => ({s with TABLE := (s.TABLE.upd (f.MODULE.TABLE.get! x) (List.append (s.TABLE.get! (f.MODULE.TABLE.get! x)) r)) }, f) + + + +def «$with_mem» : (State × Tableidx × Nat × Nat × (List Byte)) -> State + | ((s, f), x, i, j, b) => ({s with MEM := (s.MEM.upd (f.MODULE.MEM.get! x) ((s.MEM.get! (f.MODULE.MEM.get! x)).upds i j b)) }, f) + + + +def «$with_memext» : (State × Tableidx × (List Byte)) -> State + | ((s, f), x, b) => ({s with MEM := (s.MEM.upd (f.MODULE.MEM.get! x) (List.append (s.MEM.get! (f.MODULE.MEM.get! x)) b)) }, f) + + + +def «$with_elem» : (State × Elemidx × (List Ref)) -> State + | ((s, f), x, r) => ({s with ELEM := (s.ELEM.upd (f.MODULE.ELEM.get! x) r) }, f) + + + +def «$with_data» : (State × Dataidx × (List Byte)) -> State + | ((s, f), x, b) => ({s with DATA := (s.DATA.upd (f.MODULE.DATA.get! x) b) }, f) + + + + + +inductive E where + | _HOLE : E + | _SEQ : ((List Val) × E × (List Instr)) -> E + | LABEL_ : (N × (List Instr) × E) -> E + deriving Inhabited, BEq + + + +def «$unop» : (Unop_numtype × Numtype × C_numtype) -> (List C_numtype) := default + + + +def «$binop» : (Binop_numtype × Numtype × C_numtype × C_numtype) -> (List C_numtype) := default + + + +def «$testop» : (Testop_numtype × Numtype × C_numtype) -> C_numtype := default + + + +def «$relop» : (Relop_numtype × Numtype × C_numtype × C_numtype) -> C_numtype := default + + + +def «$ext» : (Nat × Nat × Sx × C_numtype) -> C_numtype := default + + + +def «$cvtop» : (Numtype × Cvtop × Numtype × (Option Sx) × C_numtype) -> (List C_numtype) := default + + + +def «$wrap_» : ((Nat × Nat) × C_numtype) -> Nat := default + +def «$bytes_» : (Nat × C_numtype) -> (List Byte) := default + +inductive Step_pure_before_ref_is_null_false : (List Admininstr) -> Prop where + | ref_is_null_true (rt : Reftype) (val : Val) : + (val == (Val.REF_NULL rt)) -> + (Step_pure_before_ref_is_null_false [(«$admininstr_val» val), Admininstr.REF_IS_NULL]) + +inductive Step_pure : ((List Admininstr) × (List Admininstr)) -> Prop where + | unreachable : + (Step_pure ([Admininstr.UNREACHABLE], [Admininstr.TRAP])) + | nop : + (Step_pure ([Admininstr.NOP], [])) + | drop (val : Val) : + (Step_pure ([(«$admininstr_val» val), Admininstr.DROP], [])) + | select_true (c : C_numtype) (t : (Option Valtype)) (val_1 : Val) (val_2 : Val) : + (c != 0) -> + (Step_pure ([(«$admininstr_val» val_1), («$admininstr_val» val_2), (Admininstr.CONST (Numtype.I32, c)), (Admininstr.SELECT t)], [(«$admininstr_val» val_1)])) + | select_false (c : C_numtype) (t : (Option Valtype)) (val_1 : Val) (val_2 : Val) : + (c == 0) -> + (Step_pure ([(«$admininstr_val» val_1), («$admininstr_val» val_2), (Admininstr.CONST (Numtype.I32, c)), (Admininstr.SELECT t)], [(«$admininstr_val» val_2)])) + | block (bt : Blocktype) (instr : (List Instr)) (k : Nat) (n : N) (t_1 : (List Valtype)) (t_2 : (List Valtype)) (val : (List Val)) : + (bt == (t_1, t_2)) -> + (Step_pure (((List.map «$admininstr_val» val) ++ [(Admininstr.BLOCK (bt, instr))]), [(Admininstr.LABEL_ (n, [], ((List.map «$admininstr_val» val) ++ (List.map «$admininstr_instr» instr))))])) + | loop (bt : Blocktype) (instr : (List Instr)) (k : Nat) (n : N) (t_1 : (List Valtype)) (t_2 : (List Valtype)) (val : (List Val)) : + (bt == (t_1, t_2)) -> + (Step_pure (((List.map «$admininstr_val» val) ++ [(Admininstr.LOOP (bt, instr))]), [(Admininstr.LABEL_ (k, [(Instr.LOOP (bt, instr))], ((List.map «$admininstr_val» val) ++ (List.map «$admininstr_instr» instr))))])) + | if_true (bt : Blocktype) (c : C_numtype) (instr_1 : (List Instr)) (instr_2 : (List Instr)) : + (c != 0) -> + (Step_pure ([(Admininstr.CONST (Numtype.I32, c)), (Admininstr.IF (bt, instr_1, instr_2))], [(Admininstr.BLOCK (bt, instr_1))])) + | if_false (bt : Blocktype) (c : C_numtype) (instr_1 : (List Instr)) (instr_2 : (List Instr)) : + (c == 0) -> + (Step_pure ([(Admininstr.CONST (Numtype.I32, c)), (Admininstr.IF (bt, instr_1, instr_2))], [(Admininstr.BLOCK (bt, instr_2))])) + | label_vals (instr : (List Instr)) (n : N) (val : (List Val)) : + (Step_pure ([(Admininstr.LABEL_ (n, instr, (List.map «$admininstr_val» val)))], (List.map «$admininstr_val» val))) + | br_zero (instr : (List Instr)) (instr' : (List Instr)) (n : N) (val : (List Val)) (val' : (List Val)) : + (Step_pure ([(Admininstr.LABEL_ (n, instr', ((List.map «$admininstr_val» val') ++ ((List.map «$admininstr_val» val) ++ ([(Admininstr.BR 0)] ++ (List.map «$admininstr_instr» instr))))))], ((List.map «$admininstr_val» val) ++ (List.map «$admininstr_instr» instr')))) + | br_succ (instr : (List Instr)) (instr' : (List Instr)) (l : Labelidx) (n : N) (val : (List Val)) : + (Step_pure ([(Admininstr.LABEL_ (n, instr', ((List.map «$admininstr_val» val) ++ ([(Admininstr.BR (l + 1))] ++ (List.map «$admininstr_instr» instr)))))], ((List.map «$admininstr_val» val) ++ [(Admininstr.BR l)]))) + | br_if_true (c : C_numtype) (l : Labelidx) : + (c != 0) -> + (Step_pure ([(Admininstr.CONST (Numtype.I32, c)), (Admininstr.BR_IF l)], [(Admininstr.BR l)])) + | br_if_false (c : C_numtype) (l : Labelidx) : + (c == 0) -> + (Step_pure ([(Admininstr.CONST (Numtype.I32, c)), (Admininstr.BR_IF l)], [])) + | br_table_lt (i : Nat) (l : (List Labelidx)) (l' : Labelidx) : + (i < l.length) -> + (Step_pure ([(Admininstr.CONST (Numtype.I32, i)), (Admininstr.BR_TABLE (l, l'))], [(Admininstr.BR (l.get! i))])) + | br_table_ge (i : Nat) (l : (List Labelidx)) (l' : Labelidx) : + (i >= l.length) -> + (Step_pure ([(Admininstr.CONST (Numtype.I32, i)), (Admininstr.BR_TABLE (l, l'))], [(Admininstr.BR l')])) + | frame_vals (f : Frame) (n : N) (val : (List Val)) : + (Step_pure ([(Admininstr.FRAME_ (n, f, (List.map «$admininstr_val» val)))], (List.map «$admininstr_val» val))) + | return_frame (f : Frame) (instr : (List Instr)) (n : N) (val : (List Val)) (val' : (List Val)) : + (Step_pure ([(Admininstr.FRAME_ (n, f, ((List.map «$admininstr_val» val') ++ ((List.map «$admininstr_val» val) ++ ([Admininstr.RETURN] ++ (List.map «$admininstr_instr» instr))))))], (List.map «$admininstr_val» val))) + | return_label (instr : (List Instr)) (instr' : (List Instr)) (k : Nat) (val : (List Val)) : + (Step_pure ([(Admininstr.LABEL_ (k, instr', ((List.map «$admininstr_val» val) ++ ([Admininstr.RETURN] ++ (List.map «$admininstr_instr» instr)))))], ((List.map «$admininstr_val» val) ++ [Admininstr.RETURN]))) + | unop_val (c : C_numtype) (c_1 : C_numtype) (nt : Numtype) (unop : Unop_numtype) : + ((«$unop» (unop, nt, c_1)) == [c]) -> + (Step_pure ([(Admininstr.CONST (nt, c_1)), (Admininstr.UNOP (nt, unop))], [(Admininstr.CONST (nt, c))])) + | unop_trap (c_1 : C_numtype) (nt : Numtype) (unop : Unop_numtype) : + ((«$unop» (unop, nt, c_1)) == []) -> + (Step_pure ([(Admininstr.CONST (nt, c_1)), (Admininstr.UNOP (nt, unop))], [Admininstr.TRAP])) + | binop_val (binop : Binop_numtype) (c : C_numtype) (c_1 : C_numtype) (c_2 : C_numtype) (nt : Numtype) : + ((«$binop» (binop, nt, c_1, c_2)) == [c]) -> + (Step_pure ([(Admininstr.CONST (nt, c_1)), (Admininstr.CONST (nt, c_2)), (Admininstr.BINOP (nt, binop))], [(Admininstr.CONST (nt, c))])) + | binop_trap (binop : Binop_numtype) (c_1 : C_numtype) (c_2 : C_numtype) (nt : Numtype) : + ((«$binop» (binop, nt, c_1, c_2)) == []) -> + (Step_pure ([(Admininstr.CONST (nt, c_1)), (Admininstr.CONST (nt, c_2)), (Admininstr.BINOP (nt, binop))], [Admininstr.TRAP])) + | testop (c : C_numtype) (c_1 : C_numtype) (nt : Numtype) (testop : Testop_numtype) : + (c == («$testop» (testop, nt, c_1))) -> + (Step_pure ([(Admininstr.CONST (nt, c_1)), (Admininstr.TESTOP (nt, testop))], [(Admininstr.CONST (Numtype.I32, c))])) + | relop (c : C_numtype) (c_1 : C_numtype) (c_2 : C_numtype) (nt : Numtype) (relop : Relop_numtype) : + (c == («$relop» (relop, nt, c_1, c_2))) -> + (Step_pure ([(Admininstr.CONST (nt, c_1)), (Admininstr.CONST (nt, c_2)), (Admininstr.RELOP (nt, relop))], [(Admininstr.CONST (Numtype.I32, c))])) + | extend (c : C_numtype) (n : N) (nt : Numtype) (o0 : Nat) : + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + (Step_pure ([(Admininstr.CONST (nt, c)), (Admininstr.EXTEND (nt, n))], [(Admininstr.CONST (nt, («$ext» (n, o0, Sx.S, c))))])) + | cvtop_val (c : C_numtype) (c_1 : C_numtype) (cvtop : Cvtop) (nt_1 : Numtype) (nt_2 : Numtype) (sx : (Option Sx)) : + ((«$cvtop» (nt_1, cvtop, nt_2, sx, c_1)) == [c]) -> + (Step_pure ([(Admininstr.CONST (nt_1, c_1)), (Admininstr.CVTOP (nt_2, cvtop, nt_1, sx))], [(Admininstr.CONST (nt_2, c))])) + | cvtop_trap (c_1 : C_numtype) (cvtop : Cvtop) (nt_1 : Numtype) (nt_2 : Numtype) (sx : (Option Sx)) : + ((«$cvtop» (nt_1, cvtop, nt_2, sx, c_1)) == []) -> + (Step_pure ([(Admininstr.CONST (nt_1, c_1)), (Admininstr.CVTOP (nt_2, cvtop, nt_1, sx))], [Admininstr.TRAP])) + | ref_is_null_true (rt : Reftype) (val : Val) : + (val == (Val.REF_NULL rt)) -> + (Step_pure ([(«$admininstr_val» val), Admininstr.REF_IS_NULL], [(Admininstr.CONST (Numtype.I32, 1))])) + | ref_is_null_false (val : Val) : + (Not (Step_pure_before_ref_is_null_false [(«$admininstr_val» val), Admininstr.REF_IS_NULL])) -> + (Step_pure ([(«$admininstr_val» val), Admininstr.REF_IS_NULL], [(Admininstr.CONST (Numtype.I32, 0))])) + | local_tee (val : Val) (x : Idx) : + (Step_pure ([(«$admininstr_val» val), (Admininstr.LOCAL_TEE x)], [(«$admininstr_val» val), («$admininstr_val» val), (Admininstr.LOCAL_SET x)])) + +inductive Step_read_before_call_indirect_trap : Config -> Prop where + | call_indirect_call (a : Addr) (ft : Functype) (ft' : Functype) (i : Nat) (instr : (List Instr)) (m : Moduleinst) (t : (List Valtype)) (x : Idx) (z : State) : + (i < («$table» (z, x)).length) -> + (a < («$funcinst» z).length) -> + (((«$table» (z, x)).get! i) == (Ref.REF_FUNC_ADDR a)) -> + (((«$funcinst» z).get! a) == (m, (ft', t, instr))) -> + (ft == ft') -> + (Step_read_before_call_indirect_trap (z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.CALL_INDIRECT (x, ft))])) + +inductive Step_read_before_table_fill_zero : Config -> Prop where + | table_fill_trap (i : Nat) (n : N) (val : Val) (x : Idx) (z : State) : + ((i + n) > («$table» (z, x)).length) -> + (Step_read_before_table_fill_zero (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_FILL x)])) + +inductive Step_read_before_table_fill_succ : Config -> Prop where + | table_fill_zero (i : Nat) (n : N) (val : Val) (x : Idx) (z : State) : + (Not (Step_read_before_table_fill_zero (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_FILL x)]))) -> + (n == 0) -> + (Step_read_before_table_fill_succ (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_FILL x)])) + | table_fill_trap (i : Nat) (n : N) (val : Val) (x : Idx) (z : State) : + ((i + n) > («$table» (z, x)).length) -> + (Step_read_before_table_fill_succ (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_FILL x)])) + +inductive Step_read_before_table_copy_zero : Config -> Prop where + | table_copy_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (((i + n) > («$table» (z, y)).length) || ((j + n) > («$table» (z, x)).length)) -> + (Step_read_before_table_copy_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))])) + +inductive Step_read_before_table_copy_le : Config -> Prop where + | table_copy_zero (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (Not (Step_read_before_table_copy_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]))) -> + (n == 0) -> + (Step_read_before_table_copy_le (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))])) + | table_copy_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (((i + n) > («$table» (z, y)).length) || ((j + n) > («$table» (z, x)).length)) -> + (Step_read_before_table_copy_le (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))])) + +inductive Step_read_before_table_copy_gt : Config -> Prop where + | table_copy_le (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (Not (Step_read_before_table_copy_le (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]))) -> + (j <= i) -> + (Step_read_before_table_copy_gt (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))])) + | table_copy_zero (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (Not (Step_read_before_table_copy_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]))) -> + (n == 0) -> + (Step_read_before_table_copy_gt (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))])) + | table_copy_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (((i + n) > («$table» (z, y)).length) || ((j + n) > («$table» (z, x)).length)) -> + (Step_read_before_table_copy_gt (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))])) + +inductive Step_read_before_table_init_zero : Config -> Prop where + | table_init_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (((i + n) > («$elem» (z, y)).length) || ((j + n) > («$table» (z, x)).length)) -> + (Step_read_before_table_init_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_INIT (x, y))])) + +inductive Step_read_before_table_init_succ : Config -> Prop where + | table_init_zero (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (Not (Step_read_before_table_init_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_INIT (x, y))]))) -> + (n == 0) -> + (Step_read_before_table_init_succ (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_INIT (x, y))])) + | table_init_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (((i + n) > («$elem» (z, y)).length) || ((j + n) > («$table» (z, x)).length)) -> + (Step_read_before_table_init_succ (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_INIT (x, y))])) + +inductive Step_read_before_memory_fill_zero : Config -> Prop where + | memory_fill_trap (i : Nat) (n : N) (val : Val) (z : State) : + ((i + n) > («$mem» (z, 0)).length) -> + (Step_read_before_memory_fill_zero (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_FILL])) + +inductive Step_read_before_memory_fill_succ : Config -> Prop where + | memory_fill_zero (i : Nat) (n : N) (val : Val) (z : State) : + (Not (Step_read_before_memory_fill_zero (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_FILL]))) -> + (n == 0) -> + (Step_read_before_memory_fill_succ (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_FILL])) + | memory_fill_trap (i : Nat) (n : N) (val : Val) (z : State) : + ((i + n) > («$mem» (z, 0)).length) -> + (Step_read_before_memory_fill_succ (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_FILL])) + +inductive Step_read_before_memory_copy_zero : Config -> Prop where + | memory_copy_trap (i : Nat) (j : Nat) (n : N) (z : State) : + (((i + n) > («$mem» (z, 0)).length) || ((j + n) > («$mem» (z, 0)).length)) -> + (Step_read_before_memory_copy_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY])) + +inductive Step_read_before_memory_copy_le : Config -> Prop where + | memory_copy_zero (i : Nat) (j : Nat) (n : N) (z : State) : + (Not (Step_read_before_memory_copy_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]))) -> + (n == 0) -> + (Step_read_before_memory_copy_le (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY])) + | memory_copy_trap (i : Nat) (j : Nat) (n : N) (z : State) : + (((i + n) > («$mem» (z, 0)).length) || ((j + n) > («$mem» (z, 0)).length)) -> + (Step_read_before_memory_copy_le (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY])) + +inductive Step_read_before_memory_copy_gt : Config -> Prop where + | memory_copy_le (i : Nat) (j : Nat) (n : N) (z : State) : + (Not (Step_read_before_memory_copy_le (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]))) -> + (j <= i) -> + (Step_read_before_memory_copy_gt (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY])) + | memory_copy_zero (i : Nat) (j : Nat) (n : N) (z : State) : + (Not (Step_read_before_memory_copy_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]))) -> + (n == 0) -> + (Step_read_before_memory_copy_gt (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY])) + | memory_copy_trap (i : Nat) (j : Nat) (n : N) (z : State) : + (((i + n) > («$mem» (z, 0)).length) || ((j + n) > («$mem» (z, 0)).length)) -> + (Step_read_before_memory_copy_gt (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY])) + +inductive Step_read_before_memory_init_zero : Config -> Prop where + | memory_init_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (z : State) : + (((i + n) > («$data» (z, x)).length) || ((j + n) > («$mem» (z, 0)).length)) -> + (Step_read_before_memory_init_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.MEMORY_INIT x)])) + +inductive Step_read_before_memory_init_succ : Config -> Prop where + | memory_init_zero (i : Nat) (j : Nat) (n : N) (x : Idx) (z : State) : + (Not (Step_read_before_memory_init_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.MEMORY_INIT x)]))) -> + (n == 0) -> + (Step_read_before_memory_init_succ (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.MEMORY_INIT x)])) + | memory_init_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (z : State) : + (((i + n) > («$data» (z, x)).length) || ((j + n) > («$mem» (z, 0)).length)) -> + (Step_read_before_memory_init_succ (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.MEMORY_INIT x)])) + +inductive Step_read : (Config × (List Admininstr)) -> Prop where + | call (x : Idx) (z : State) : + (x < («$funcaddr» z).length) -> + (Step_read ((z, [(Admininstr.CALL x)]), [(Admininstr.CALL_ADDR ((«$funcaddr» z).get! x))])) + | call_indirect_call (a : Addr) (ft : Functype) (ft' : Functype) (i : Nat) (instr : (List Instr)) (m : Moduleinst) (t : (List Valtype)) (x : Idx) (z : State) : + (i < («$table» (z, x)).length) -> + (a < («$funcinst» z).length) -> + (((«$table» (z, x)).get! i) == (Ref.REF_FUNC_ADDR a)) -> + (((«$funcinst» z).get! a) == (m, (ft', t, instr))) -> + (ft == ft') -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.CALL_INDIRECT (x, ft))]), [(Admininstr.CALL_ADDR a)])) + | call_indirect_trap (ft : Functype) (i : Nat) (x : Idx) (z : State) : + (Not (Step_read_before_call_indirect_trap (z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.CALL_INDIRECT (x, ft))]))) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.CALL_INDIRECT (x, ft))]), [Admininstr.TRAP])) + | call_addr (a : Addr) (f : Frame) (instr : (List Instr)) (k : Nat) (m : Moduleinst) (n : N) (t : (List Valtype)) (t_1 : (List Valtype)) (t_2 : (List Valtype)) (val : (List Val)) (z : State) (o0 : (List Val)) : + (t.length == o0.length) -> + (a < («$funcinst» z).length) -> + (Forall₂ (λ t o0 ↦ ((«$default_» t) == (some o0))) t o0) -> + (((«$funcinst» z).get! a) == (m, ((t_1, t_2), t, instr))) -> + (f == {LOCAL := (val ++ o0), MODULE := m}) -> + (Step_read ((z, ((List.map «$admininstr_val» val) ++ [(Admininstr.CALL_ADDR a)])), [(Admininstr.FRAME_ (n, f, [(Admininstr.LABEL_ (n, [], (List.map «$admininstr_instr» instr)))]))])) + | ref_func (x : Idx) (z : State) : + (x < («$funcaddr» z).length) -> + (Step_read ((z, [(Admininstr.REF_FUNC x)]), [(Admininstr.REF_FUNC_ADDR ((«$funcaddr» z).get! x))])) + | local_get (x : Idx) (z : State) : + (Step_read ((z, [(Admininstr.LOCAL_GET x)]), [(«$admininstr_val» («$local» (z, x)))])) + | global_get (x : Idx) (z : State) : + (Step_read ((z, [(Admininstr.GLOBAL_GET x)]), [(«$admininstr_globalinst» («$global» (z, x)))])) + | table_get_trap (i : Nat) (x : Idx) (z : State) : + (i >= («$table» (z, x)).length) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.TABLE_GET x)]), [Admininstr.TRAP])) + | table_get_val (i : Nat) (x : Idx) (z : State) : + (i < («$table» (z, x)).length) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.TABLE_GET x)]), [(«$admininstr_ref» ((«$table» (z, x)).get! i))])) + | table_size (n : N) (x : Idx) (z : State) : + ((«$table» (z, x)).length == n) -> + (Step_read ((z, [(Admininstr.TABLE_SIZE x)]), [(Admininstr.CONST (Numtype.I32, n))])) + | table_fill_trap (i : Nat) (n : N) (val : Val) (x : Idx) (z : State) : + ((i + n) > («$table» (z, x)).length) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_FILL x)]), [Admininstr.TRAP])) + | table_fill_zero (i : Nat) (n : N) (val : Val) (x : Idx) (z : State) : + (Not (Step_read_before_table_fill_zero (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_FILL x)]))) -> + (n == 0) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_FILL x)]), [])) + | table_fill_succ (i : Nat) (n : N) (val : Val) (x : Idx) (z : State) : + (Not (Step_read_before_table_fill_succ (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_FILL x)]))) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_FILL x)]), [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.TABLE_SET x), (Admininstr.CONST (Numtype.I32, (i + 1))), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, (n - 1))), (Admininstr.TABLE_FILL x)])) + | table_copy_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (((i + n) > («$table» (z, y)).length) || ((j + n) > («$table» (z, x)).length)) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]), [Admininstr.TRAP])) + | table_copy_zero (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (Not (Step_read_before_table_copy_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]))) -> + (n == 0) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]), [])) + | table_copy_le (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (Not (Step_read_before_table_copy_le (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]))) -> + (j <= i) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]), [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.TABLE_GET y), (Admininstr.TABLE_SET x), (Admininstr.CONST (Numtype.I32, (j + 1))), (Admininstr.CONST (Numtype.I32, (i + 1))), (Admininstr.CONST (Numtype.I32, (n - 1))), (Admininstr.TABLE_COPY (x, y))])) + | table_copy_gt (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (Not (Step_read_before_table_copy_gt (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]))) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_COPY (x, y))]), [(Admininstr.CONST (Numtype.I32, ((j + n) - 1))), (Admininstr.CONST (Numtype.I32, ((i + n) - 1))), (Admininstr.TABLE_GET y), (Admininstr.TABLE_SET x), (Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, (n - 1))), (Admininstr.TABLE_COPY (x, y))])) + | table_init_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (((i + n) > («$elem» (z, y)).length) || ((j + n) > («$table» (z, x)).length)) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_INIT (x, y))]), [Admininstr.TRAP])) + | table_init_zero (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (Not (Step_read_before_table_init_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_INIT (x, y))]))) -> + (n == 0) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_INIT (x, y))]), [])) + | table_init_succ (i : Nat) (j : Nat) (n : N) (x : Idx) (y : Idx) (z : State) : + (i < («$elem» (z, y)).length) -> + (Not (Step_read_before_table_init_succ (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_INIT (x, y))]))) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_INIT (x, y))]), [(Admininstr.CONST (Numtype.I32, j)), («$admininstr_ref» ((«$elem» (z, y)).get! i)), (Admininstr.TABLE_SET x), (Admininstr.CONST (Numtype.I32, (j + 1))), (Admininstr.CONST (Numtype.I32, (i + 1))), (Admininstr.CONST (Numtype.I32, (n - 1))), (Admininstr.TABLE_INIT (x, y))])) + | load_num_trap (i : Nat) (n_A : N) (n_O : N) (nt : Numtype) (z : State) (o0 : Nat) : + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + (((i + n_O) + (((Nat.div o0) 8))) > («$mem» (z, 0)).length) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.LOAD (nt, none, n_A, n_O))]), [Admininstr.TRAP])) + | load_num_val (c : C_numtype) (i : Nat) (n_A : N) (n_O : N) (nt : Numtype) (z : State) (o0 : Nat) (o1 : Nat) : + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + ((«$size» («$valtype_numtype» nt)) == (some o1)) -> + ((«$bytes_» (o0, c)) == ((«$mem» (z, 0)).slice (i + n_O) (((Nat.div o1) 8)))) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.LOAD (nt, none, n_A, n_O))]), [(Admininstr.CONST (nt, c))])) + | load_pack_trap (i : Nat) (n : N) (n_A : N) (n_O : N) (nt : Numtype) (sx : Sx) (z : State) : + (((i + n_O) + (((Nat.div n) 8))) > («$mem» (z, 0)).length) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.LOAD (nt, (some (n, sx)), n_A, n_O))]), [Admininstr.TRAP])) + | load_pack_val (c : C_numtype) (i : Nat) (n : N) (n_A : N) (n_O : N) (nt : Numtype) (sx : Sx) (z : State) (o0 : Nat) : + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + ((«$bytes_» (n, c)) == ((«$mem» (z, 0)).slice (i + n_O) (((Nat.div n) 8)))) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.LOAD (nt, (some (n, sx)), n_A, n_O))]), [(Admininstr.CONST (nt, («$ext» (n, o0, sx, c))))])) + | memory_size (n : N) (z : State) : + (((n * 64) * («$Ki» ())) == («$mem» (z, 0)).length) -> + (Step_read ((z, [Admininstr.MEMORY_SIZE]), [(Admininstr.CONST (Numtype.I32, n))])) + | memory_fill_trap (i : Nat) (n : N) (val : Val) (z : State) : + ((i + n) > («$mem» (z, 0)).length) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_FILL]), [Admininstr.TRAP])) + | memory_fill_zero (i : Nat) (n : N) (val : Val) (z : State) : + (Not (Step_read_before_memory_fill_zero (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_FILL]))) -> + (n == 0) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_FILL]), [])) + | memory_fill_succ (i : Nat) (n : N) (val : Val) (z : State) : + (Not (Step_read_before_memory_fill_succ (z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_FILL]))) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_FILL]), [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_val» val), (Admininstr.STORE (Numtype.I32, (some 8), 0, 0)), (Admininstr.CONST (Numtype.I32, (i + 1))), («$admininstr_val» val), (Admininstr.CONST (Numtype.I32, (n - 1))), Admininstr.MEMORY_FILL])) + | memory_copy_trap (i : Nat) (j : Nat) (n : N) (z : State) : + (((i + n) > («$mem» (z, 0)).length) || ((j + n) > («$mem» (z, 0)).length)) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]), [Admininstr.TRAP])) + | memory_copy_zero (i : Nat) (j : Nat) (n : N) (z : State) : + (Not (Step_read_before_memory_copy_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]))) -> + (n == 0) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]), [])) + | memory_copy_le (i : Nat) (j : Nat) (n : N) (z : State) : + (Not (Step_read_before_memory_copy_le (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]))) -> + (j <= i) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]), [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.LOAD (Numtype.I32, (some (8, Sx.U)), 0, 0)), (Admininstr.STORE (Numtype.I32, (some 8), 0, 0)), (Admininstr.CONST (Numtype.I32, (j + 1))), (Admininstr.CONST (Numtype.I32, (i + 1))), (Admininstr.CONST (Numtype.I32, (n - 1))), Admininstr.MEMORY_COPY])) + | memory_copy_gt (i : Nat) (j : Nat) (n : N) (z : State) : + (Not (Step_read_before_memory_copy_gt (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]))) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_COPY]), [(Admininstr.CONST (Numtype.I32, ((j + n) - 1))), (Admininstr.CONST (Numtype.I32, ((i + n) - 1))), (Admininstr.LOAD (Numtype.I32, (some (8, Sx.U)), 0, 0)), (Admininstr.STORE (Numtype.I32, (some 8), 0, 0)), (Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, (n - 1))), Admininstr.MEMORY_COPY])) + | memory_init_trap (i : Nat) (j : Nat) (n : N) (x : Idx) (z : State) : + (((i + n) > («$data» (z, x)).length) || ((j + n) > («$mem» (z, 0)).length)) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.MEMORY_INIT x)]), [Admininstr.TRAP])) + | memory_init_zero (i : Nat) (j : Nat) (n : N) (x : Idx) (z : State) : + (Not (Step_read_before_memory_init_zero (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.MEMORY_INIT x)]))) -> + (n == 0) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.MEMORY_INIT x)]), [])) + | memory_init_succ (i : Nat) (j : Nat) (n : N) (x : Idx) (z : State) : + (i < («$data» (z, x)).length) -> + (Not (Step_read_before_memory_init_succ (z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.MEMORY_INIT x)]))) -> + (Step_read ((z, [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.MEMORY_INIT x)]), [(Admininstr.CONST (Numtype.I32, j)), (Admininstr.CONST (Numtype.I32, ((«$data» (z, x)).get! i))), (Admininstr.STORE (Numtype.I32, (some 8), 0, 0)), (Admininstr.CONST (Numtype.I32, (j + 1))), (Admininstr.CONST (Numtype.I32, (i + 1))), (Admininstr.CONST (Numtype.I32, (n - 1))), (Admininstr.MEMORY_INIT x)])) + +inductive Step : (Config × Config) -> Prop where + | pure (instr : (List Instr)) (instr' : (List Instr)) (z : State) : + (Step_pure ((List.map «$admininstr_instr» instr), (List.map «$admininstr_instr» instr'))) -> + (Step ((z, (List.map «$admininstr_instr» instr)), (z, (List.map «$admininstr_instr» instr')))) + | read (instr : (List Instr)) (instr' : (List Instr)) (z : State) : + (Step_read ((z, (List.map «$admininstr_instr» instr)), (List.map «$admininstr_instr» instr'))) -> + (Step ((z, (List.map «$admininstr_instr» instr)), (z, (List.map «$admininstr_instr» instr')))) + | local_set (val : Val) (x : Idx) (z : State) : + (Step ((z, [(«$admininstr_val» val), (Admininstr.LOCAL_SET x)]), ((«$with_local» (z, x, val)), []))) + | global_set (val : Val) (x : Idx) (z : State) : + (Step ((z, [(«$admininstr_val» val), (Admininstr.GLOBAL_SET x)]), ((«$with_global» (z, x, val)), []))) + | table_set_trap (i : Nat) (ref : Ref) (x : Idx) (z : State) : + (i >= («$table» (z, x)).length) -> + (Step ((z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_ref» ref), (Admininstr.TABLE_GET x)]), (z, [Admininstr.TRAP]))) + | table_set_val (i : Nat) (ref : Ref) (x : Idx) (z : State) : + (i < («$table» (z, x)).length) -> + (Step ((z, [(Admininstr.CONST (Numtype.I32, i)), («$admininstr_ref» ref), (Admininstr.TABLE_GET x)]), ((«$with_table» (z, x, i, ref)), []))) + | table_grow_succeed (n : N) (ref : Ref) (x : Idx) (z : State) : + (Step ((z, [(«$admininstr_ref» ref), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_GROW x)]), ((«$with_tableext» (z, x, [ref])), [(Admininstr.CONST (Numtype.I32, («$table» (z, x)).length))]))) + | table_grow_fail (n : N) (ref : Ref) (x : Idx) (z : State) : + (Step ((z, [(«$admininstr_ref» ref), (Admininstr.CONST (Numtype.I32, n)), (Admininstr.TABLE_GROW x)]), (z, [(Admininstr.CONST (Numtype.I32, (0 - 1)))]))) + | elem_drop (x : Idx) (z : State) : + (Step ((z, [(Admininstr.ELEM_DROP x)]), ((«$with_elem» (z, x, [])), []))) + | store_num_trap (c : C_numtype) (i : Nat) (n_A : N) (n_O : N) (nt : Numtype) (z : State) (o0 : Nat) : + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + (((i + n_O) + (((Nat.div o0) 8))) > («$mem» (z, 0)).length) -> + (Step ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (nt, c)), (Admininstr.STORE (nt, none, n_A, n_O))]), (z, [Admininstr.TRAP]))) + | store_num_val (b : (List Byte)) (c : C_numtype) (i : Nat) (n_A : N) (n_O : N) (nt : Numtype) (z : State) (o0 : Nat) (o1 : Nat) : + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + ((«$size» («$valtype_numtype» nt)) == (some o1)) -> + (b == («$bytes_» (o1, c))) -> + (Step ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (nt, c)), (Admininstr.STORE (nt, none, n_A, n_O))]), ((«$with_mem» (z, 0, (i + n_O), (((Nat.div o0) 8)), b)), []))) + | store_pack_trap (c : C_numtype) (i : Nat) (n : N) (n_A : N) (n_O : N) (nt : Numtype) (z : State) : + (((i + n_O) + (((Nat.div n) 8))) > («$mem» (z, 0)).length) -> + (Step ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (nt, c)), (Admininstr.STORE (nt, (some n), n_A, n_O))]), (z, [Admininstr.TRAP]))) + | store_pack_val (b : (List Byte)) (c : C_numtype) (i : Nat) (n : N) (n_A : N) (n_O : N) (nt : Numtype) (z : State) (o0 : Nat) : + ((«$size» («$valtype_numtype» nt)) == (some o0)) -> + (b == («$bytes_» (n, («$wrap_» ((o0, n), c))))) -> + (Step ((z, [(Admininstr.CONST (Numtype.I32, i)), (Admininstr.CONST (nt, c)), (Admininstr.STORE (nt, (some n), n_A, n_O))]), ((«$with_mem» (z, 0, (i + n_O), (((Nat.div n) 8)), b)), []))) + | memory_grow_succeed (n : N) (z : State) : + (Step ((z, [(Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_GROW]), ((«$with_memext» (z, 0, [0])), [(Admininstr.CONST (Numtype.I32, (((Nat.div («$mem» (z, 0)).length) (64 * («$Ki» ()))))))]))) + | memory_grow_fail (n : N) (z : State) : + (Step ((z, [(Admininstr.CONST (Numtype.I32, n)), Admininstr.MEMORY_GROW]), (z, [(Admininstr.CONST (Numtype.I32, (0 - 1)))]))) + | data_drop (x : Idx) (z : State) : + (Step ((z, [(Admininstr.DATA_DROP x)]), ((«$with_data» (z, x, [])), []))) + + + + + diff --git a/spectec/test-lean4/dune b/spectec/test-lean4/dune new file mode 100644 index 0000000000..b6698d4379 --- /dev/null +++ b/spectec/test-lean4/dune @@ -0,0 +1,27 @@ +(rule + (targets watsup.stderr.current SpecTec.lean.current lean.stdout.current) + (deps + (file ../src/exe-watsup/main.exe) + (glob_files ../spec/*.watsup) + ) + (action + (progn + (write-file SpecTec.lean.current "not generated") + (with-stderr-to watsup.stderr.current (run %{deps} --lean4 -o SpecTec.lean.current)) + (with-stdout-to lean.stdout.current (run ./run-lean.sh SpecTec.lean.current)) + ) + ) +) + +(rule + (alias runtest) + (action (diff watsup.stderr watsup.stderr.current)) +) +(rule + (alias runtest) + (action (diff SpecTec.lean SpecTec.lean.current)) +) +(rule + (alias runtest) + (action (progn (diff lean.stdout lean.stdout.current))) +) diff --git a/spectec/test-lean4/lean.stdout b/spectec/test-lean4/lean.stdout new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spectec/test-lean4/run-lean.sh b/spectec/test-lean4/run-lean.sh new file mode 100755 index 0000000000..f77eec5376 --- /dev/null +++ b/spectec/test-lean4/run-lean.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +lean "$1" 2>&1 | sed -e 's,/[^ ]*/toolchains,.../toolchains`,g' | sed -e 's,SpecTec.lean:[0-9]\+:[0-9]\+,SpecTec.lean,' | sed -e 's,\?m\.[0-9]\+,?m,g' diff --git a/spectec/test-lean4/watsup.stderr b/spectec/test-lean4/watsup.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spectec/test-middlend/TEST.md b/spectec/test-middlend/TEST.md index 6af2e43e18..5f7599d86a 100644 --- a/spectec/test-middlend/TEST.md +++ b/spectec/test-middlend/TEST.md @@ -10375,6 +10375,1983 @@ relation Step: `%~>%`(config, config) rule data.drop {x : idx, z : state}: `%~>%`(`%;%*`(z, [DATA.DROP_admininstr(x)]), `%;%*`($with_data(z, x, []), [])) +== IL Validation... +== Running pass else-elimination + +;; 1-syntax.watsup:3.1-3.15 +syntax n = nat + +;; 1-syntax.watsup:9.1-9.37 +syntax name = text + +;; 1-syntax.watsup:14.1-14.36 +syntax byte = nat + +;; 1-syntax.watsup:15.1-15.45 +syntax u32 = nat + +;; 1-syntax.watsup:22.1-22.36 +syntax idx = nat + +;; 1-syntax.watsup:23.1-23.49 +syntax funcidx = idx + +;; 1-syntax.watsup:24.1-24.49 +syntax globalidx = idx + +;; 1-syntax.watsup:25.1-25.47 +syntax tableidx = idx + +;; 1-syntax.watsup:26.1-26.46 +syntax memidx = idx + +;; 1-syntax.watsup:27.1-27.45 +syntax elemidx = idx + +;; 1-syntax.watsup:28.1-28.45 +syntax dataidx = idx + +;; 1-syntax.watsup:29.1-29.47 +syntax labelidx = idx + +;; 1-syntax.watsup:30.1-30.47 +syntax localidx = idx + +;; 1-syntax.watsup:39.1-40.22 +syntax numtype = + | I32 + | I64 + | F32 + | F64 + +;; 1-syntax.watsup:41.1-42.5 +syntax vectype = + | V128 + +;; 1-syntax.watsup:43.1-44.20 +syntax reftype = + | FUNCREF + | EXTERNREF + +;; 1-syntax.watsup:45.1-46.34 +syntax valtype = + | I32 + | I64 + | F32 + | F64 + | V128 + | FUNCREF + | EXTERNREF + | BOT + +def valtype_numtype : numtype -> valtype + def valtype_numtype(I32_numtype) = I32_valtype + def valtype_numtype(I64_numtype) = I64_valtype + def valtype_numtype(F32_numtype) = F32_valtype + def valtype_numtype(F64_numtype) = F64_valtype + +def valtype_reftype : reftype -> valtype + def valtype_reftype(FUNCREF_reftype) = FUNCREF_valtype + def valtype_reftype(EXTERNREF_reftype) = EXTERNREF_valtype + +def valtype_vectype : vectype -> valtype + def valtype_vectype(V128_vectype) = V128_valtype + +;; 1-syntax.watsup:48.1-48.39 +syntax in = + | I32 + | I64 + +def numtype_in : in -> numtype + def numtype_in(I32_in) = I32_numtype + def numtype_in(I64_in) = I64_numtype + +def valtype_in : in -> valtype + def valtype_in(I32_in) = I32_valtype + def valtype_in(I64_in) = I64_valtype + +;; 1-syntax.watsup:49.1-49.39 +syntax fn = + | F32 + | F64 + +def numtype_fn : fn -> numtype + def numtype_fn(F32_fn) = F32_numtype + def numtype_fn(F64_fn) = F64_numtype + +def valtype_fn : fn -> valtype + def valtype_fn(F32_fn) = F32_valtype + def valtype_fn(F64_fn) = F64_valtype + +;; 1-syntax.watsup:56.1-57.11 +syntax resulttype = valtype* + +;; 1-syntax.watsup:59.1-60.16 +syntax limits = `[%..%]`(u32, u32) + +;; 1-syntax.watsup:61.1-62.15 +syntax globaltype = `MUT%?%`(()?, valtype) + +;; 1-syntax.watsup:63.1-64.27 +syntax functype = `%->%`(resulttype, resulttype) + +;; 1-syntax.watsup:65.1-66.17 +syntax tabletype = `%%`(limits, reftype) + +;; 1-syntax.watsup:67.1-68.12 +syntax memtype = `%I8`(limits) + +;; 1-syntax.watsup:69.1-70.10 +syntax elemtype = reftype + +;; 1-syntax.watsup:71.1-72.5 +syntax datatype = OK + +;; 1-syntax.watsup:73.1-74.66 +syntax externtype = + | GLOBAL(globaltype) + | FUNC(functype) + | TABLE(tabletype) + | MEM(memtype) + +;; 1-syntax.watsup:86.1-86.44 +syntax sx = + | U + | S + +;; 1-syntax.watsup:88.1-88.39 +syntax unop_IXX = + | CLZ + | CTZ + | POPCNT + +;; 1-syntax.watsup:89.1-89.70 +syntax unop_FXX = + | ABS + | NEG + | SQRT + | CEIL + | FLOOR + | TRUNC + | NEAREST + +;; 1-syntax.watsup:91.1-93.62 +syntax binop_IXX = + | ADD + | SUB + | MUL + | DIV(sx) + | REM(sx) + | AND + | OR + | XOR + | SHL + | SHR(sx) + | ROTL + | ROTR + +;; 1-syntax.watsup:94.1-94.66 +syntax binop_FXX = + | ADD + | SUB + | MUL + | DIV + | MIN + | MAX + | COPYSIGN + +;; 1-syntax.watsup:96.1-96.26 +syntax testop_IXX = + | EQZ + +;; 1-syntax.watsup:97.1-97.22 +syntax testop_FXX = + | + +;; 1-syntax.watsup:99.1-100.108 +syntax relop_IXX = + | EQ + | NE + | LT(sx) + | GT(sx) + | LE(sx) + | GE(sx) + +;; 1-syntax.watsup:101.1-101.49 +syntax relop_FXX = + | EQ + | NE + | LT + | GT + | LE + | GE + +;; 1-syntax.watsup:103.1-103.50 +syntax unop_numtype = + | _I(unop_IXX) + | _F(unop_FXX) + +;; 1-syntax.watsup:104.1-104.53 +syntax binop_numtype = + | _I(binop_IXX) + | _F(binop_FXX) + +;; 1-syntax.watsup:105.1-105.56 +syntax testop_numtype = + | _I(testop_IXX) + | _F(testop_FXX) + +;; 1-syntax.watsup:106.1-106.53 +syntax relop_numtype = + | _I(relop_IXX) + | _F(relop_FXX) + +;; 1-syntax.watsup:107.1-107.39 +syntax cvtop = + | CONVERT + | REINTERPRET + +;; 1-syntax.watsup:117.1-117.23 +syntax c_numtype = nat + +;; 1-syntax.watsup:118.1-118.23 +syntax c_vectype = nat + +;; 1-syntax.watsup:121.1-121.52 +syntax blocktype = functype + +;; 1-syntax.watsup:156.1-177.80 +rec { + +;; 1-syntax.watsup:156.1-177.80 +syntax instr = + | UNREACHABLE + | NOP + | DROP + | SELECT(valtype?) + | BLOCK(blocktype, instr*) + | LOOP(blocktype, instr*) + | IF(blocktype, instr*, instr*) + | BR(labelidx) + | BR_IF(labelidx) + | BR_TABLE(labelidx*, labelidx) + | CALL(funcidx) + | CALL_INDIRECT(tableidx, functype) + | RETURN + | CONST(numtype, c_numtype) + | UNOP(numtype, unop_numtype) + | BINOP(numtype, binop_numtype) + | TESTOP(numtype, testop_numtype) + | RELOP(numtype, relop_numtype) + | EXTEND(numtype, n) + | CVTOP(numtype, cvtop, numtype, sx?) + | REF.NULL(reftype) + | REF.FUNC(funcidx) + | REF.IS_NULL + | LOCAL.GET(localidx) + | LOCAL.SET(localidx) + | LOCAL.TEE(localidx) + | GLOBAL.GET(globalidx) + | GLOBAL.SET(globalidx) + | TABLE.GET(tableidx) + | TABLE.SET(tableidx) + | TABLE.SIZE(tableidx) + | TABLE.GROW(tableidx) + | TABLE.FILL(tableidx) + | TABLE.COPY(tableidx, tableidx) + | TABLE.INIT(tableidx, elemidx) + | ELEM.DROP(elemidx) + | MEMORY.SIZE + | MEMORY.GROW + | MEMORY.FILL + | MEMORY.COPY + | MEMORY.INIT(dataidx) + | DATA.DROP(dataidx) + | LOAD(numtype, (n, sx)?, u32, u32) + | STORE(numtype, n?, u32, u32) +} + +;; 1-syntax.watsup:179.1-180.9 +syntax expr = instr* + +;; 1-syntax.watsup:187.1-187.50 +syntax elemmode = + | TABLE(tableidx, expr) + | DECLARE + +;; 1-syntax.watsup:188.1-188.39 +syntax datamode = + | MEMORY(memidx, expr) + +;; 1-syntax.watsup:190.1-191.30 +syntax func = `FUNC%%*%`(functype, valtype*, expr) + +;; 1-syntax.watsup:192.1-193.25 +syntax global = GLOBAL(globaltype, expr) + +;; 1-syntax.watsup:194.1-195.18 +syntax table = TABLE(tabletype) + +;; 1-syntax.watsup:196.1-197.17 +syntax mem = MEMORY(memtype) + +;; 1-syntax.watsup:198.1-199.31 +syntax elem = `ELEM%%*%?`(reftype, expr*, elemmode?) + +;; 1-syntax.watsup:200.1-201.26 +syntax data = `DATA(*)%*%?`(byte**, datamode?) + +;; 1-syntax.watsup:202.1-203.16 +syntax start = START(funcidx) + +;; 1-syntax.watsup:205.1-206.62 +syntax externuse = + | FUNC(funcidx) + | GLOBAL(globalidx) + | TABLE(tableidx) + | MEM(memidx) + +;; 1-syntax.watsup:207.1-208.24 +syntax export = EXPORT(name, externuse) + +;; 1-syntax.watsup:209.1-210.30 +syntax import = IMPORT(name, name, externtype) + +;; 1-syntax.watsup:212.1-213.70 +syntax module = `MODULE%*%*%*%*%*%*%*%?%*`(import*, func*, global*, table*, mem*, elem*, data*, start?, export*) + +;; 2-aux.watsup:3.1-3.14 +def Ki : nat + ;; 2-aux.watsup:4.1-4.15 + def Ki = 1024 + +;; 2-aux.watsup:9.1-9.25 +rec { + +;; 2-aux.watsup:9.1-9.25 +def min : (nat, nat) -> nat + ;; 2-aux.watsup:10.1-10.19 + def {j : nat} min(0, j) = 0 + ;; 2-aux.watsup:11.1-11.19 + def {i : nat} min(i, 0) = 0 + ;; 2-aux.watsup:12.1-12.38 + def {i : nat, j : nat} min((i + 1), (j + 1)) = $min(i, j) +} + +;; 2-aux.watsup:19.1-19.55 +def size : valtype -> nat? + ;; 2-aux.watsup:20.1-20.20 + def size(I32_valtype) = ?(32) + ;; 2-aux.watsup:21.1-21.20 + def size(I64_valtype) = ?(64) + ;; 2-aux.watsup:22.1-22.20 + def size(F32_valtype) = ?(32) + ;; 2-aux.watsup:23.1-23.20 + def size(F64_valtype) = ?(64) + ;; 2-aux.watsup:24.1-24.22 + def size(V128_valtype) = ?(128) + def {x : valtype} size(x) = ?() + +;; 2-aux.watsup:29.1-29.40 +def test_sub_ATOM_22 : n -> nat + ;; 2-aux.watsup:30.1-30.38 + def {n_3_ATOM_y : n} test_sub_ATOM_22(n_3_ATOM_y) = 0 + +;; 2-aux.watsup:32.1-32.26 +def curried_ : (n, n) -> nat + ;; 2-aux.watsup:33.1-33.39 + def {n_1 : n, n_2 : n} curried_(n_1, n_2) = (n_1 + n_2) + +;; 2-aux.watsup:35.1-44.39 +syntax testfuse = + | AB_(nat, nat, nat) + | CD(nat, nat, nat) + | EF(nat, nat, nat) + | GH(nat, nat, nat) + | IJ(nat, nat, nat) + | KL(nat, nat, nat) + | MN(nat, nat, nat) + | OP(nat, nat, nat) + | QR(nat, nat, nat) + +;; 3-typing.watsup:3.1-6.60 +syntax context = {FUNC functype*, GLOBAL globaltype*, TABLE tabletype*, MEM memtype*, ELEM elemtype*, DATA datatype*, LOCAL valtype*, LABEL resulttype*, RETURN resulttype?} + +;; 3-typing.watsup:14.1-14.66 +relation Limits_ok: `|-%:%`(limits, nat) + ;; 3-typing.watsup:22.1-24.24 + rule _ {k : nat, n_1 : n, n_2 : n}: + `|-%:%`(`[%..%]`(n_1, n_2), k) + -- if ((n_1 <= n_2) /\ (n_2 <= k)) + +;; 3-typing.watsup:15.1-15.64 +relation Functype_ok: `|-%:OK`(functype) + ;; 3-typing.watsup:26.1-27.13 + rule _ {ft : functype}: + `|-%:OK`(ft) + +;; 3-typing.watsup:16.1-16.66 +relation Globaltype_ok: `|-%:OK`(globaltype) + ;; 3-typing.watsup:29.1-30.13 + rule _ {gt : globaltype}: + `|-%:OK`(gt) + +;; 3-typing.watsup:17.1-17.65 +relation Tabletype_ok: `|-%:OK`(tabletype) + ;; 3-typing.watsup:32.1-34.35 + rule _ {lim : limits, rt : reftype}: + `|-%:OK`(`%%`(lim, rt)) + -- Limits_ok: `|-%:%`(lim, ((2 ^ 32) - 1)) + +;; 3-typing.watsup:18.1-18.63 +relation Memtype_ok: `|-%:OK`(memtype) + ;; 3-typing.watsup:36.1-38.33 + rule _ {lim : limits}: + `|-%:OK`(`%I8`(lim)) + -- Limits_ok: `|-%:%`(lim, (2 ^ 16)) + +;; 3-typing.watsup:19.1-19.66 +relation Externtype_ok: `|-%:OK`(externtype) + ;; 3-typing.watsup:41.1-43.35 + rule func {functype : functype}: + `|-%:OK`(FUNC_externtype(functype)) + -- Functype_ok: `|-%:OK`(functype) + + ;; 3-typing.watsup:45.1-47.39 + rule global {globaltype : globaltype}: + `|-%:OK`(GLOBAL_externtype(globaltype)) + -- Globaltype_ok: `|-%:OK`(globaltype) + + ;; 3-typing.watsup:49.1-51.37 + rule table {tabletype : tabletype}: + `|-%:OK`(TABLE_externtype(tabletype)) + -- Tabletype_ok: `|-%:OK`(tabletype) + + ;; 3-typing.watsup:53.1-55.33 + rule mem {memtype : memtype}: + `|-%:OK`(MEM_externtype(memtype)) + -- Memtype_ok: `|-%:OK`(memtype) + +;; 3-typing.watsup:61.1-61.65 +relation Valtype_sub: `|-%<:%`(valtype, valtype) + ;; 3-typing.watsup:64.1-65.12 + rule refl {t : valtype}: + `|-%<:%`(t, t) + + ;; 3-typing.watsup:67.1-68.14 + rule bot {t : valtype}: + `|-%<:%`(BOT_valtype, t) + +;; 3-typing.watsup:62.1-62.72 +relation Resulttype_sub: `|-%*<:%*`(valtype*, valtype*) + ;; 3-typing.watsup:70.1-72.35 + rule _ {t_1* : valtype*, t_2* : valtype*}: + `|-%*<:%*`(t_1*{t_1}, t_2*{t_2}) + -- if (|t_1*{t_1}| = |t_2*{t_2}|) + -- (Valtype_sub: `|-%<:%`(t_1, t_2))*{t_1 t_2} + +;; 3-typing.watsup:75.1-75.75 +relation Limits_sub: `|-%<:%`(limits, limits) + ;; 3-typing.watsup:83.1-86.21 + rule _ {n_11 : n, n_12 : n, n_21 : n, n_22 : n}: + `|-%<:%`(`[%..%]`(n_11, n_12), `[%..%]`(n_21, n_22)) + -- if (n_11 >= n_21) + -- if (n_12 <= n_22) + +;; 3-typing.watsup:76.1-76.73 +relation Functype_sub: `|-%<:%`(functype, functype) + ;; 3-typing.watsup:88.1-89.14 + rule _ {ft : functype}: + `|-%<:%`(ft, ft) + +;; 3-typing.watsup:77.1-77.75 +relation Globaltype_sub: `|-%<:%`(globaltype, globaltype) + ;; 3-typing.watsup:91.1-92.14 + rule _ {gt : globaltype}: + `|-%<:%`(gt, gt) + +;; 3-typing.watsup:78.1-78.74 +relation Tabletype_sub: `|-%<:%`(tabletype, tabletype) + ;; 3-typing.watsup:94.1-96.35 + rule _ {lim_1 : limits, lim_2 : limits, rt : reftype}: + `|-%<:%`(`%%`(lim_1, rt), `%%`(lim_2, rt)) + -- Limits_sub: `|-%<:%`(lim_1, lim_2) + +;; 3-typing.watsup:79.1-79.72 +relation Memtype_sub: `|-%<:%`(memtype, memtype) + ;; 3-typing.watsup:98.1-100.35 + rule _ {lim_1 : limits, lim_2 : limits}: + `|-%<:%`(`%I8`(lim_1), `%I8`(lim_2)) + -- Limits_sub: `|-%<:%`(lim_1, lim_2) + +;; 3-typing.watsup:80.1-80.75 +relation Externtype_sub: `|-%<:%`(externtype, externtype) + ;; 3-typing.watsup:103.1-105.35 + rule func {ft_1 : functype, ft_2 : functype}: + `|-%<:%`(FUNC_externtype(ft_1), FUNC_externtype(ft_2)) + -- Functype_sub: `|-%<:%`(ft_1, ft_2) + + ;; 3-typing.watsup:107.1-109.37 + rule global {gt_1 : globaltype, gt_2 : globaltype}: + `|-%<:%`(GLOBAL_externtype(gt_1), GLOBAL_externtype(gt_2)) + -- Globaltype_sub: `|-%<:%`(gt_1, gt_2) + + ;; 3-typing.watsup:111.1-113.36 + rule table {tt_1 : tabletype, tt_2 : tabletype}: + `|-%<:%`(TABLE_externtype(tt_1), TABLE_externtype(tt_2)) + -- Tabletype_sub: `|-%<:%`(tt_1, tt_2) + + ;; 3-typing.watsup:115.1-117.34 + rule mem {mt_1 : memtype, mt_2 : memtype}: + `|-%<:%`(MEM_externtype(mt_1), MEM_externtype(mt_2)) + -- Memtype_sub: `|-%<:%`(mt_1, mt_2) + +;; 3-typing.watsup:172.1-172.76 +relation Blocktype_ok: `%|-%:%`(context, blocktype, functype) + ;; 3-typing.watsup:174.1-176.29 + rule _ {C : context, ft : functype}: + `%|-%:%`(C, ft, ft) + -- Functype_ok: `|-%:OK`(ft) + +;; 3-typing.watsup:123.1-124.67 +rec { + +;; 3-typing.watsup:123.1-123.66 +relation Instr_ok: `%|-%:%`(context, instr, functype) + ;; 3-typing.watsup:153.1-154.34 + rule unreachable {C : context, t_1* : valtype*, t_2* : valtype*}: + `%|-%:%`(C, UNREACHABLE_instr, `%->%`(t_1*{t_1}, t_2*{t_2})) + + ;; 3-typing.watsup:156.1-157.32 + rule nop {C : context}: + `%|-%:%`(C, NOP_instr, `%->%`([], [])) + + ;; 3-typing.watsup:159.1-160.27 + rule drop {C : context, t : valtype}: + `%|-%:%`(C, DROP_instr, `%->%`([t], [])) + + ;; 3-typing.watsup:163.1-164.31 + rule select-expl {C : context, t : valtype}: + `%|-%:%`(C, SELECT_instr(?(t)), `%->%`([t t I32_valtype], [t])) + + ;; 3-typing.watsup:166.1-169.37 + rule select-impl {C : context, numtype : numtype, t : valtype, t' : valtype, vectype : vectype}: + `%|-%:%`(C, SELECT_instr(?()), `%->%`([t t I32_valtype], [t])) + -- Valtype_sub: `|-%<:%`(t, t') + -- if ((t' = $valtype_numtype(numtype)) \/ (t' = $valtype_vectype(vectype))) + + ;; 3-typing.watsup:178.1-181.57 + rule block {C : context, bt : blocktype, instr* : instr*, t_1* : valtype*, t_2* : valtype*}: + `%|-%:%`(C, BLOCK_instr(bt, instr*{instr}), `%->%`(t_1*{t_1}, t_2*{t_2})) + -- Blocktype_ok: `%|-%:%`(C, bt, `%->%`(t_1*{t_1}, t_2*{t_2})) + -- InstrSeq_ok: `%|-%*:%`(C ++ {FUNC [], GLOBAL [], TABLE [], MEM [], ELEM [], DATA [], LOCAL [], LABEL [t_2]*{t_2}, RETURN ?()}, instr*{instr}, `%->%`(t_1*{t_1}, t_2*{t_2})) + + ;; 3-typing.watsup:183.1-186.57 + rule loop {C : context, bt : blocktype, instr* : instr*, t_1* : valtype*, t_2* : valtype*}: + `%|-%:%`(C, LOOP_instr(bt, instr*{instr}), `%->%`(t_1*{t_1}, t_2*{t_2})) + -- Blocktype_ok: `%|-%:%`(C, bt, `%->%`(t_1*{t_1}, t_2*{t_2})) + -- InstrSeq_ok: `%|-%*:%`(C ++ {FUNC [], GLOBAL [], TABLE [], MEM [], ELEM [], DATA [], LOCAL [], LABEL [t_1]*{t_1}, RETURN ?()}, instr*{instr}, `%->%`(t_1*{t_1}, t_2*{t_2})) + + ;; 3-typing.watsup:188.1-192.59 + rule if {C : context, bt : blocktype, instr_1* : instr*, instr_2* : instr*, t_1* : valtype*, t_2* : valtype*}: + `%|-%:%`(C, IF_instr(bt, instr_1*{instr_1}, instr_2*{instr_2}), `%->%`(t_1*{t_1}, t_2*{t_2})) + -- Blocktype_ok: `%|-%:%`(C, bt, `%->%`(t_1*{t_1}, t_2*{t_2})) + -- InstrSeq_ok: `%|-%*:%`(C ++ {FUNC [], GLOBAL [], TABLE [], MEM [], ELEM [], DATA [], LOCAL [], LABEL [t_2]*{t_2}, RETURN ?()}, instr_1*{instr_1}, `%->%`(t_1*{t_1}, t_2*{t_2})) + -- InstrSeq_ok: `%|-%*:%`(C ++ {FUNC [], GLOBAL [], TABLE [], MEM [], ELEM [], DATA [], LOCAL [], LABEL [t_2]*{t_2}, RETURN ?()}, instr_2*{instr_2}, `%->%`(t_1*{t_1}, t_2*{t_2})) + + ;; 3-typing.watsup:195.1-197.24 + rule br {C : context, l : labelidx, t* : valtype*, t_1* : valtype*, t_2* : valtype*}: + `%|-%:%`(C, BR_instr(l), `%->%`(t_1*{t_1} :: t*{t}, t_2*{t_2})) + -- if (l < |C.LABEL_context|) + -- if (C.LABEL_context[l] = t*{t}) + + ;; 3-typing.watsup:199.1-201.24 + rule br_if {C : context, l : labelidx, t* : valtype*}: + `%|-%:%`(C, BR_IF_instr(l), `%->%`(t*{t} :: [I32_valtype], t*{t})) + -- if (l < |C.LABEL_context|) + -- if (C.LABEL_context[l] = t*{t}) + + ;; 3-typing.watsup:203.1-206.42 + rule br_table {C : context, l* : labelidx*, l' : labelidx, t* : valtype*, t_1* : valtype*, t_2* : valtype*}: + `%|-%:%`(C, BR_TABLE_instr(l*{l}, l'), `%->%`(t_1*{t_1} :: t*{t}, t_2*{t_2})) + -- (if (l < |C.LABEL_context|))*{l} + -- if (l' < |C.LABEL_context|) + -- (Resulttype_sub: `|-%*<:%*`(t*{t}, C.LABEL_context[l]))*{l} + -- Resulttype_sub: `|-%*<:%*`(t*{t}, C.LABEL_context[l']) + + ;; 3-typing.watsup:208.1-210.24 + rule return {C : context, t* : valtype*, t_1* : valtype*, t_2* : valtype*}: + `%|-%:%`(C, RETURN_instr, `%->%`(t_1*{t_1} :: t*{t}, t_2*{t_2})) + -- if (C.RETURN_context = ?(t*{t})) + + ;; 3-typing.watsup:212.1-214.33 + rule call {C : context, t_1* : valtype*, t_2* : valtype*, x : idx}: + `%|-%:%`(C, CALL_instr(x), `%->%`(t_1*{t_1}, t_2*{t_2})) + -- if (x < |C.FUNC_context|) + -- if (C.FUNC_context[x] = `%->%`(t_1*{t_1}, t_2*{t_2})) + + ;; 3-typing.watsup:216.1-219.26 + rule call_indirect {C : context, ft : functype, lim : limits, t_1* : valtype*, t_2* : valtype*, x : idx}: + `%|-%:%`(C, CALL_INDIRECT_instr(x, ft), `%->%`(t_1*{t_1} :: [I32_valtype], t_2*{t_2})) + -- if (x < |C.TABLE_context|) + -- if (C.TABLE_context[x] = `%%`(lim, FUNCREF_reftype)) + -- if (ft = `%->%`(t_1*{t_1}, t_2*{t_2})) + + ;; 3-typing.watsup:222.1-223.37 + rule const {C : context, c_nt : c_numtype, nt : numtype}: + `%|-%:%`(C, CONST_instr(nt, c_nt), `%->%`([], [$valtype_numtype(nt)])) + + ;; 3-typing.watsup:225.1-226.31 + rule unop {C : context, nt : numtype, unop : unop_numtype}: + `%|-%:%`(C, UNOP_instr(nt, unop), `%->%`([$valtype_numtype(nt)], [$valtype_numtype(nt)])) + + ;; 3-typing.watsup:228.1-229.36 + rule binop {C : context, binop : binop_numtype, nt : numtype}: + `%|-%:%`(C, BINOP_instr(nt, binop), `%->%`([$valtype_numtype(nt) $valtype_numtype(nt)], [$valtype_numtype(nt)])) + + ;; 3-typing.watsup:231.1-232.36 + rule testop {C : context, nt : numtype, testop : testop_numtype}: + `%|-%:%`(C, TESTOP_instr(nt, testop), `%->%`([$valtype_numtype(nt)], [I32_valtype])) + + ;; 3-typing.watsup:234.1-235.37 + rule relop {C : context, nt : numtype, relop : relop_numtype}: + `%|-%:%`(C, RELOP_instr(nt, relop), `%->%`([$valtype_numtype(nt) $valtype_numtype(nt)], [I32_valtype])) + + ;; 3-typing.watsup:238.1-240.23 + rule extend {C : context, n : n, nt : numtype, o0 : nat}: + `%|-%:%`(C, EXTEND_instr(nt, n), `%->%`([$valtype_numtype(nt)], [$valtype_numtype(nt)])) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + -- if (n <= o0) + + ;; 3-typing.watsup:242.1-245.34 + rule reinterpret {C : context, nt_1 : numtype, nt_2 : numtype, o0 : nat, o1 : nat}: + `%|-%:%`(C, CVTOP_instr(nt_1, REINTERPRET_cvtop, nt_2, ?()), `%->%`([$valtype_numtype(nt_2)], [$valtype_numtype(nt_1)])) + -- if ($size($valtype_numtype(nt_1)) = ?(o0)) + -- if ($size($valtype_numtype(nt_2)) = ?(o1)) + -- if (nt_1 =/= nt_2) + -- if (o0 = o1) + + ;; 3-typing.watsup:247.1-250.52 + rule convert-i {C : context, in_1 : in, in_2 : in, sx? : sx?, o0 : nat, o1 : nat}: + `%|-%:%`(C, CVTOP_instr($numtype_in(in_1), CONVERT_cvtop, $numtype_in(in_2), sx?{sx}), `%->%`([$valtype_in(in_2)], [$valtype_in(in_1)])) + -- if ($size($valtype_in(in_1)) = ?(o0)) + -- if ($size($valtype_in(in_2)) = ?(o1)) + -- if (in_1 =/= in_2) + -- if ((sx?{sx} = ?()) <=> (o0 > o1)) + + ;; 3-typing.watsup:252.1-254.22 + rule convert-f {C : context, fn_1 : fn, fn_2 : fn}: + `%|-%:%`(C, CVTOP_instr($numtype_fn(fn_1), CONVERT_cvtop, $numtype_fn(fn_2), ?()), `%->%`([$valtype_fn(fn_2)], [$valtype_fn(fn_1)])) + -- if (fn_1 =/= fn_2) + + ;; 3-typing.watsup:257.1-258.35 + rule ref.null {C : context, rt : reftype}: + `%|-%:%`(C, REF.NULL_instr(rt), `%->%`([], [$valtype_reftype(rt)])) + + ;; 3-typing.watsup:260.1-262.23 + rule ref.func {C : context, ft : functype, x : idx}: + `%|-%:%`(C, REF.FUNC_instr(x), `%->%`([], [FUNCREF_valtype])) + -- if (x < |C.FUNC_context|) + -- if (C.FUNC_context[x] = ft) + + ;; 3-typing.watsup:264.1-265.31 + rule ref.is_null {C : context, rt : reftype}: + `%|-%:%`(C, REF.IS_NULL_instr, `%->%`([$valtype_reftype(rt)], [I32_valtype])) + + ;; 3-typing.watsup:268.1-270.23 + rule local.get {C : context, t : valtype, x : idx}: + `%|-%:%`(C, LOCAL.GET_instr(x), `%->%`([], [t])) + -- if (x < |C.LOCAL_context|) + -- if (C.LOCAL_context[x] = t) + + ;; 3-typing.watsup:272.1-274.23 + rule local.set {C : context, t : valtype, x : idx}: + `%|-%:%`(C, LOCAL.SET_instr(x), `%->%`([t], [])) + -- if (x < |C.LOCAL_context|) + -- if (C.LOCAL_context[x] = t) + + ;; 3-typing.watsup:276.1-278.23 + rule local.tee {C : context, t : valtype, x : idx}: + `%|-%:%`(C, LOCAL.TEE_instr(x), `%->%`([t], [t])) + -- if (x < |C.LOCAL_context|) + -- if (C.LOCAL_context[x] = t) + + ;; 3-typing.watsup:281.1-283.29 + rule global.get {C : context, t : valtype, x : idx, w0 : ()?}: + `%|-%:%`(C, GLOBAL.GET_instr(x), `%->%`([], [t])) + -- if (x < |C.GLOBAL_context|) + -- if (C.GLOBAL_context[x] = `MUT%?%`(w0, t)) + + ;; 3-typing.watsup:285.1-287.28 + rule global.set {C : context, t : valtype, x : idx}: + `%|-%:%`(C, GLOBAL.SET_instr(x), `%->%`([t], [])) + -- if (x < |C.GLOBAL_context|) + -- if (C.GLOBAL_context[x] = `MUT%?%`(?(()), t)) + + ;; 3-typing.watsup:290.1-292.28 + rule table.get {C : context, lim : limits, rt : reftype, x : idx}: + `%|-%:%`(C, TABLE.GET_instr(x), `%->%`([I32_valtype], [$valtype_reftype(rt)])) + -- if (x < |C.TABLE_context|) + -- if (C.TABLE_context[x] = `%%`(lim, rt)) + + ;; 3-typing.watsup:294.1-296.28 + rule table.set {C : context, lim : limits, rt : reftype, x : idx}: + `%|-%:%`(C, TABLE.SET_instr(x), `%->%`([I32_valtype $valtype_reftype(rt)], [])) + -- if (x < |C.TABLE_context|) + -- if (C.TABLE_context[x] = `%%`(lim, rt)) + + ;; 3-typing.watsup:298.1-300.24 + rule table.size {C : context, tt : tabletype, x : idx}: + `%|-%:%`(C, TABLE.SIZE_instr(x), `%->%`([], [I32_valtype])) + -- if (x < |C.TABLE_context|) + -- if (C.TABLE_context[x] = tt) + + ;; 3-typing.watsup:302.1-304.28 + rule table.grow {C : context, lim : limits, rt : reftype, x : idx}: + `%|-%:%`(C, TABLE.GROW_instr(x), `%->%`([$valtype_reftype(rt) I32_valtype], [I32_valtype])) + -- if (x < |C.TABLE_context|) + -- if (C.TABLE_context[x] = `%%`(lim, rt)) + + ;; 3-typing.watsup:306.1-308.28 + rule table.fill {C : context, lim : limits, rt : reftype, x : idx}: + `%|-%:%`(C, TABLE.FILL_instr(x), `%->%`([I32_valtype $valtype_reftype(rt) I32_valtype], [])) + -- if (x < |C.TABLE_context|) + -- if (C.TABLE_context[x] = `%%`(lim, rt)) + + ;; 3-typing.watsup:310.1-313.32 + rule table.copy {C : context, lim_1 : limits, lim_2 : limits, rt : reftype, x_1 : idx, x_2 : idx}: + `%|-%:%`(C, TABLE.COPY_instr(x_1, x_2), `%->%`([I32_valtype I32_valtype I32_valtype], [])) + -- if (x_1 < |C.TABLE_context|) + -- if (x_2 < |C.TABLE_context|) + -- if (C.TABLE_context[x_1] = `%%`(lim_1, rt)) + -- if (C.TABLE_context[x_2] = `%%`(lim_2, rt)) + + ;; 3-typing.watsup:315.1-318.25 + rule table.init {C : context, lim : limits, rt : reftype, x_1 : idx, x_2 : idx}: + `%|-%:%`(C, TABLE.INIT_instr(x_1, x_2), `%->%`([I32_valtype I32_valtype I32_valtype], [])) + -- if (x_1 < |C.TABLE_context|) + -- if (x_2 < |C.ELEM_context|) + -- if (C.TABLE_context[x_1] = `%%`(lim, rt)) + -- if (C.ELEM_context[x_2] = rt) + + ;; 3-typing.watsup:320.1-322.23 + rule elem.drop {C : context, rt : reftype, x : idx}: + `%|-%:%`(C, ELEM.DROP_instr(x), `%->%`([], [])) + -- if (x < |C.ELEM_context|) + -- if (C.ELEM_context[x] = rt) + + ;; 3-typing.watsup:325.1-327.22 + rule memory.size {C : context, mt : memtype}: + `%|-%:%`(C, MEMORY.SIZE_instr, `%->%`([], [I32_valtype])) + -- if (0 < |C.MEM_context|) + -- if (C.MEM_context[0] = mt) + + ;; 3-typing.watsup:329.1-331.22 + rule memory.grow {C : context, mt : memtype}: + `%|-%:%`(C, MEMORY.GROW_instr, `%->%`([I32_valtype], [I32_valtype])) + -- if (0 < |C.MEM_context|) + -- if (C.MEM_context[0] = mt) + + ;; 3-typing.watsup:333.1-335.22 + rule memory.fill {C : context, mt : memtype}: + `%|-%:%`(C, MEMORY.FILL_instr, `%->%`([I32_valtype I32_valtype I32_valtype], [I32_valtype])) + -- if (0 < |C.MEM_context|) + -- if (C.MEM_context[0] = mt) + + ;; 3-typing.watsup:337.1-339.22 + rule memory.copy {C : context, mt : memtype}: + `%|-%:%`(C, MEMORY.COPY_instr, `%->%`([I32_valtype I32_valtype I32_valtype], [I32_valtype])) + -- if (0 < |C.MEM_context|) + -- if (C.MEM_context[0] = mt) + + ;; 3-typing.watsup:341.1-344.23 + rule memory.init {C : context, mt : memtype, x : idx}: + `%|-%:%`(C, MEMORY.INIT_instr(x), `%->%`([I32_valtype I32_valtype I32_valtype], [I32_valtype])) + -- if (0 < |C.MEM_context|) + -- if (x < |C.DATA_context|) + -- if (C.MEM_context[0] = mt) + -- if (C.DATA_context[x] = OK) + + ;; 3-typing.watsup:346.1-348.23 + rule data.drop {C : context, x : idx}: + `%|-%:%`(C, DATA.DROP_instr(x), `%->%`([], [])) + -- if (x < |C.DATA_context|) + -- if (C.DATA_context[x] = OK) + + ;; 3-typing.watsup:350.1-355.32 + rule load {C : context, in : in, mt : memtype, n? : n?, n_A : n, n_O : n, nt : numtype, sx? : sx?, o0 : nat, o1? : nat?}: + `%|-%:%`(C, LOAD_instr(nt, (n, sx)?{n sx}, n_A, n_O), `%->%`([I32_valtype], [$valtype_numtype(nt)])) + -- if (0 < |C.MEM_context|) + -- if ((n?{n} = ?()) <=> (o1?{o1} = ?())) + -- if ((n?{n} = ?()) <=> (sx?{sx} = ?())) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + -- (if ($size($valtype_numtype(nt)) = ?(o1)))?{o1} + -- if (C.MEM_context[0] = mt) + -- if ((2 ^ n_A) <= (o0 / 8)) + -- (if (((2 ^ n_A) <= (n / 8)) /\ ((n / 8) < (o1 / 8))))?{n o1} + -- if ((n?{n} = ?()) \/ (nt = $numtype_in(in))) + + ;; 3-typing.watsup:357.1-362.32 + rule store {C : context, in : in, mt : memtype, n? : n?, n_A : n, n_O : n, nt : numtype, o0 : nat, o1? : nat?}: + `%|-%:%`(C, STORE_instr(nt, n?{n}, n_A, n_O), `%->%`([I32_valtype $valtype_numtype(nt)], [])) + -- if (0 < |C.MEM_context|) + -- if ((n?{n} = ?()) <=> (o1?{o1} = ?())) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + -- (if ($size($valtype_numtype(nt)) = ?(o1)))?{o1} + -- if (C.MEM_context[0] = mt) + -- if ((2 ^ n_A) <= (o0 / 8)) + -- (if (((2 ^ n_A) <= (n / 8)) /\ ((n / 8) < (o1 / 8))))?{n o1} + -- if ((n?{n} = ?()) \/ (nt = $numtype_in(in))) + +;; 3-typing.watsup:124.1-124.67 +relation InstrSeq_ok: `%|-%*:%`(context, instr*, functype) + ;; 3-typing.watsup:133.1-134.36 + rule empty {C : context}: + `%|-%*:%`(C, [], `%->%`([], [])) + + ;; 3-typing.watsup:136.1-139.46 + rule seq {C : context, instr_1 : instr, instr_2 : instr, t_1* : valtype*, t_2* : valtype*, t_3* : valtype*}: + `%|-%*:%`(C, [instr_1] :: instr_2*{}, `%->%`(t_1*{t_1}, t_3*{t_3})) + -- Instr_ok: `%|-%:%`(C, instr_1, `%->%`(t_1*{t_1}, t_2*{t_2})) + -- InstrSeq_ok: `%|-%*:%`(C, [instr_2], `%->%`(t_2*{t_2}, t_3*{t_3})) + + ;; 3-typing.watsup:141.1-146.38 + rule weak {C : context, instr* : instr*, t'_1* : valtype*, t'_2* : valtype*, t_1* : valtype*, t_2* : valtype*}: + `%|-%*:%`(C, instr*{instr}, `%->%`(t'_1*{t'_1}, t'_2*{t'_2})) + -- InstrSeq_ok: `%|-%*:%`(C, instr*{instr}, `%->%`(t_1*{t_1}, t_2*{t_2})) + -- Resulttype_sub: `|-%*<:%*`(t'_1*{t'_1}, t_1*{t_1}) + -- Resulttype_sub: `|-%*<:%*`(t_2*{t_2}, t'_2*{t'_2}) + + ;; 3-typing.watsup:148.1-150.45 + rule frame {C : context, instr* : instr*, t* : valtype*, t_1* : valtype*, t_2* : valtype*}: + `%|-%*:%`(C, instr*{instr}, `%->%`(t*{t} :: t_1*{t_1}, t*{t} :: t_2*{t_2})) + -- InstrSeq_ok: `%|-%*:%`(C, instr*{instr}, `%->%`(t_1*{t_1}, t_2*{t_2})) +} + +;; 3-typing.watsup:125.1-125.71 +relation Expr_ok: `%|-%:%`(context, expr, resulttype) + ;; 3-typing.watsup:128.1-130.46 + rule _ {C : context, instr* : instr*, t* : valtype*}: + `%|-%:%`(C, instr*{instr}, t*{t}) + -- InstrSeq_ok: `%|-%*:%`(C, instr*{instr}, `%->%`([], t*{t})) + +;; 3-typing.watsup:367.1-367.78 +relation Instr_const: `%|-%CONST`(context, instr) + ;; 3-typing.watsup:371.1-372.26 + rule const {C : context, c : c_numtype, nt : numtype}: + `%|-%CONST`(C, CONST_instr(nt, c)) + + ;; 3-typing.watsup:374.1-375.27 + rule ref.null {C : context, rt : reftype}: + `%|-%CONST`(C, REF.NULL_instr(rt)) + + ;; 3-typing.watsup:377.1-378.26 + rule ref.func {C : context, x : idx}: + `%|-%CONST`(C, REF.FUNC_instr(x)) + + ;; 3-typing.watsup:380.1-382.32 + rule global.get {C : context, t : valtype, x : idx}: + `%|-%CONST`(C, GLOBAL.GET_instr(x)) + -- if (x < |C.GLOBAL_context|) + -- if (C.GLOBAL_context[x] = `MUT%?%`(?(), t)) + +;; 3-typing.watsup:368.1-368.77 +relation Expr_const: `%|-%CONST`(context, expr) + ;; 3-typing.watsup:385.1-386.38 + rule _ {C : context, instr* : instr*}: + `%|-%CONST`(C, instr*{instr}) + -- (Instr_const: `%|-%CONST`(C, instr))*{instr} + +;; 3-typing.watsup:369.1-369.78 +relation Expr_ok_const: `%|-%:%CONST`(context, expr, valtype) + ;; 3-typing.watsup:389.1-392.33 + rule _ {C : context, expr : expr, t : valtype}: + `%|-%:%CONST`(C, expr, t) + -- Expr_ok: `%|-%:%`(C, expr, [t]) + -- Expr_const: `%|-%CONST`(C, expr) + +;; 3-typing.watsup:397.1-397.73 +relation Func_ok: `%|-%:%`(context, func, functype) + ;; 3-typing.watsup:408.1-412.75 + rule _ {C : context, expr : expr, ft : functype, t* : valtype*, t_1* : valtype*, t_2* : valtype*}: + `%|-%:%`(C, `FUNC%%*%`(ft, t*{t}, expr), ft) + -- if (ft = `%->%`(t_1*{t_1}, t_2*{t_2})) + -- Functype_ok: `|-%:OK`(ft) + -- Expr_ok: `%|-%:%`(C ++ {FUNC [], GLOBAL [], TABLE [], MEM [], ELEM [], DATA [], LOCAL t_1*{t_1} :: t*{t}, LABEL [], RETURN ?()} ++ {FUNC [], GLOBAL [], TABLE [], MEM [], ELEM [], DATA [], LOCAL [], LABEL [t_2*{t_2}], RETURN ?()} ++ {FUNC [], GLOBAL [], TABLE [], MEM [], ELEM [], DATA [], LOCAL [], LABEL [], RETURN ?(t_2*{t_2})}, expr, t_2*{t_2}) + +;; 3-typing.watsup:398.1-398.75 +relation Global_ok: `%|-%:%`(context, global, globaltype) + ;; 3-typing.watsup:414.1-418.40 + rule _ {C : context, expr : expr, gt : globaltype, t : valtype, w0 : ()?}: + `%|-%:%`(C, GLOBAL(gt, expr), gt) + -- Globaltype_ok: `|-%:OK`(gt) + -- if (gt = `MUT%?%`(w0, t)) + -- Expr_ok_const: `%|-%:%CONST`(C, expr, t) + +;; 3-typing.watsup:399.1-399.74 +relation Table_ok: `%|-%:%`(context, table, tabletype) + ;; 3-typing.watsup:420.1-422.30 + rule _ {C : context, tt : tabletype}: + `%|-%:%`(C, TABLE(tt), tt) + -- Tabletype_ok: `|-%:OK`(tt) + +;; 3-typing.watsup:400.1-400.72 +relation Mem_ok: `%|-%:%`(context, mem, memtype) + ;; 3-typing.watsup:424.1-426.28 + rule _ {C : context, mt : memtype}: + `%|-%:%`(C, MEMORY(mt), mt) + -- Memtype_ok: `|-%:OK`(mt) + +;; 3-typing.watsup:403.1-403.77 +relation Elemmode_ok: `%|-%:%`(context, elemmode, reftype) + ;; 3-typing.watsup:437.1-440.45 + rule active {C : context, expr : expr, lim : limits, rt : reftype, x : idx}: + `%|-%:%`(C, TABLE_elemmode(x, expr), rt) + -- if (x < |C.TABLE_context|) + -- if (C.TABLE_context[x] = `%%`(lim, rt)) + -- (Expr_ok_const: `%|-%:%CONST`(C, expr, I32_valtype))*{} + + ;; 3-typing.watsup:442.1-443.20 + rule declare {C : context, rt : reftype}: + `%|-%:%`(C, DECLARE_elemmode, rt) + +;; 3-typing.watsup:401.1-401.73 +relation Elem_ok: `%|-%:%`(context, elem, reftype) + ;; 3-typing.watsup:428.1-431.40 + rule _ {C : context, elemmode? : elemmode?, expr* : expr*, rt : reftype}: + `%|-%:%`(C, `ELEM%%*%?`(rt, expr*{expr}, elemmode?{elemmode}), rt) + -- (Expr_ok: `%|-%:%`(C, expr, [$valtype_reftype(rt)]))*{expr} + -- (Elemmode_ok: `%|-%:%`(C, elemmode, rt))?{elemmode} + +;; 3-typing.watsup:404.1-404.77 +relation Datamode_ok: `%|-%:OK`(context, datamode) + ;; 3-typing.watsup:445.1-448.45 + rule _ {C : context, expr : expr, mt : memtype}: + `%|-%:OK`(C, MEMORY_datamode(0, expr)) + -- if (0 < |C.MEM_context|) + -- if (C.MEM_context[0] = mt) + -- (Expr_ok_const: `%|-%:%CONST`(C, expr, I32_valtype))*{} + +;; 3-typing.watsup:402.1-402.73 +relation Data_ok: `%|-%:OK`(context, data) + ;; 3-typing.watsup:433.1-435.40 + rule _ {C : context, b** : byte**, datamode? : datamode?}: + `%|-%:OK`(C, `DATA(*)%*%?`(b*{b}*{b}, datamode?{datamode})) + -- (Datamode_ok: `%|-%:OK`(C, datamode))?{datamode} + +;; 3-typing.watsup:405.1-405.74 +relation Start_ok: `%|-%:OK`(context, start) + ;; 3-typing.watsup:450.1-452.39 + rule _ {C : context, x : idx}: + `%|-%:OK`(C, START(x)) + -- if (x < |C.FUNC_context|) + -- if (C.FUNC_context[x] = `%->%`([], [])) + +;; 3-typing.watsup:455.1-455.80 +relation Import_ok: `%|-%:%`(context, import, externtype) + ;; 3-typing.watsup:459.1-461.31 + rule _ {C : context, name_1 : name, name_2 : name, xt : externtype}: + `%|-%:%`(C, IMPORT(name_1, name_2, xt), xt) + -- Externtype_ok: `|-%:OK`(xt) + +;; 3-typing.watsup:457.1-457.83 +relation Externuse_ok: `%|-%:%`(context, externuse, externtype) + ;; 3-typing.watsup:467.1-469.23 + rule func {C : context, ft : functype, x : idx}: + `%|-%:%`(C, FUNC_externuse(x), FUNC_externtype(ft)) + -- if (x < |C.FUNC_context|) + -- if (C.FUNC_context[x] = ft) + + ;; 3-typing.watsup:471.1-473.25 + rule global {C : context, gt : globaltype, x : idx}: + `%|-%:%`(C, GLOBAL_externuse(x), GLOBAL_externtype(gt)) + -- if (x < |C.GLOBAL_context|) + -- if (C.GLOBAL_context[x] = gt) + + ;; 3-typing.watsup:475.1-477.24 + rule table {C : context, tt : tabletype, x : idx}: + `%|-%:%`(C, TABLE_externuse(x), TABLE_externtype(tt)) + -- if (x < |C.TABLE_context|) + -- if (C.TABLE_context[x] = tt) + + ;; 3-typing.watsup:479.1-481.22 + rule mem {C : context, mt : memtype, x : idx}: + `%|-%:%`(C, MEM_externuse(x), MEM_externtype(mt)) + -- if (x < |C.MEM_context|) + -- if (C.MEM_context[x] = mt) + +;; 3-typing.watsup:456.1-456.80 +relation Export_ok: `%|-%:%`(context, export, externtype) + ;; 3-typing.watsup:463.1-465.39 + rule _ {C : context, externuse : externuse, name : name, xt : externtype}: + `%|-%:%`(C, EXPORT(name, externuse), xt) + -- Externuse_ok: `%|-%:%`(C, externuse, xt) + +;; 3-typing.watsup:484.1-484.62 +relation Module_ok: `|-%:OK`(module) + ;; 3-typing.watsup:486.1-500.16 + rule _ {C : context, data^n : data^n, elem* : elem*, export* : export*, ft* : functype*, func* : func*, global* : global*, gt* : globaltype*, import* : import*, mem* : mem*, mt* : memtype*, n : n, rt* : reftype*, start? : start?, table* : table*, tt* : tabletype*}: + `|-%:OK`(`MODULE%*%*%*%*%*%*%*%?%*`(import*{import}, func*{func}, global*{global}, table*{table}, mem*{mem}, elem*{elem}, data^n{data}, start?{start}, export*{export})) + -- if (|ft*{ft}| = |func*{func}|) + -- if (|global*{global}| = |gt*{gt}|) + -- if (|table*{table}| = |tt*{tt}|) + -- if (|mem*{mem}| = |mt*{mt}|) + -- if (|elem*{elem}| = |rt*{rt}|) + -- if (C = {FUNC ft*{ft}, GLOBAL gt*{gt}, TABLE tt*{tt}, MEM mt*{mt}, ELEM rt*{rt}, DATA OK^n{}, LOCAL [], LABEL [], RETURN ?()}) + -- (Func_ok: `%|-%:%`(C, func, ft))*{ft func} + -- (Global_ok: `%|-%:%`(C, global, gt))*{global gt} + -- (Table_ok: `%|-%:%`(C, table, tt))*{table tt} + -- (Mem_ok: `%|-%:%`(C, mem, mt))*{mem mt} + -- (Elem_ok: `%|-%:%`(C, elem, rt))*{elem rt} + -- (Data_ok: `%|-%:OK`(C, data))^n{data} + -- (Start_ok: `%|-%:OK`(C, start))?{start} + -- if (|mem*{mem}| <= 1) + +;; 4-runtime.watsup:3.1-3.39 +syntax addr = nat + +;; 4-runtime.watsup:4.1-4.53 +syntax funcaddr = addr + +;; 4-runtime.watsup:5.1-5.53 +syntax globaladdr = addr + +;; 4-runtime.watsup:6.1-6.51 +syntax tableaddr = addr + +;; 4-runtime.watsup:7.1-7.50 +syntax memaddr = addr + +;; 4-runtime.watsup:8.1-8.49 +syntax elemaddr = addr + +;; 4-runtime.watsup:9.1-9.49 +syntax dataaddr = addr + +;; 4-runtime.watsup:10.1-10.51 +syntax labeladdr = addr + +;; 4-runtime.watsup:11.1-11.49 +syntax hostaddr = addr + +;; 4-runtime.watsup:24.1-25.24 +syntax num = + | CONST(numtype, c_numtype) + +;; 4-runtime.watsup:26.1-27.67 +syntax ref = + | REF.NULL(reftype) + | REF.FUNC_ADDR(funcaddr) + | REF.HOST_ADDR(hostaddr) + +;; 4-runtime.watsup:28.1-29.10 +syntax val = + | CONST(numtype, c_numtype) + | REF.NULL(reftype) + | REF.FUNC_ADDR(funcaddr) + | REF.HOST_ADDR(hostaddr) + +;; 4-runtime.watsup:31.1-32.18 +syntax result = + | _VALS(val*) + | TRAP + +;; 4-runtime.watsup:38.1-39.66 +syntax externval = + | FUNC(funcaddr) + | GLOBAL(globaladdr) + | TABLE(tableaddr) + | MEM(memaddr) + +;; 4-runtime.watsup:44.1-44.44 +def default_ : valtype -> val? + ;; 4-runtime.watsup:45.1-45.35 + def default_(I32_valtype) = ?(CONST_val(I32_numtype, 0)) + ;; 4-runtime.watsup:46.1-46.35 + def default_(I64_valtype) = ?(CONST_val(I64_numtype, 0)) + ;; 4-runtime.watsup:47.1-47.35 + def default_(F32_valtype) = ?(CONST_val(F32_numtype, 0)) + ;; 4-runtime.watsup:48.1-48.35 + def default_(F64_valtype) = ?(CONST_val(F64_numtype, 0)) + ;; 4-runtime.watsup:49.1-49.44 + def default_(FUNCREF_valtype) = ?(REF.NULL_val(FUNCREF_reftype)) + ;; 4-runtime.watsup:50.1-50.48 + def default_(EXTERNREF_valtype) = ?(REF.NULL_val(EXTERNREF_reftype)) + def {x : valtype} default_(x) = ?() + +;; 4-runtime.watsup:61.1-61.71 +syntax exportinst = EXPORT(name, externval) + +;; 4-runtime.watsup:71.1-78.25 +syntax moduleinst = {FUNC funcaddr*, GLOBAL globaladdr*, TABLE tableaddr*, MEM memaddr*, ELEM elemaddr*, DATA dataaddr*, EXPORT exportinst*} + +;; 4-runtime.watsup:55.1-55.66 +syntax funcinst = `%;%`(moduleinst, func) + +;; 4-runtime.watsup:56.1-56.53 +syntax globalinst = val + +;; 4-runtime.watsup:57.1-57.52 +syntax tableinst = ref* + +;; 4-runtime.watsup:58.1-58.52 +syntax meminst = byte* + +;; 4-runtime.watsup:59.1-59.53 +syntax eleminst = ref* + +;; 4-runtime.watsup:60.1-60.51 +syntax datainst = byte* + +;; 4-runtime.watsup:63.1-69.21 +syntax store = {FUNC funcinst*, GLOBAL globalinst*, TABLE tableinst*, MEM meminst*, ELEM eleminst*, DATA datainst*} + +;; 4-runtime.watsup:80.1-82.24 +syntax frame = {LOCAL val*, MODULE moduleinst} + +;; 4-runtime.watsup:83.1-83.47 +syntax state = `%;%`(store, frame) + +;; 4-runtime.watsup:146.1-153.5 +rec { + +;; 4-runtime.watsup:146.1-153.5 +syntax admininstr = + | UNREACHABLE + | NOP + | DROP + | SELECT(valtype?) + | BLOCK(blocktype, instr*) + | LOOP(blocktype, instr*) + | IF(blocktype, instr*, instr*) + | BR(labelidx) + | BR_IF(labelidx) + | BR_TABLE(labelidx*, labelidx) + | CALL(funcidx) + | CALL_INDIRECT(tableidx, functype) + | RETURN + | CONST(numtype, c_numtype) + | UNOP(numtype, unop_numtype) + | BINOP(numtype, binop_numtype) + | TESTOP(numtype, testop_numtype) + | RELOP(numtype, relop_numtype) + | EXTEND(numtype, n) + | CVTOP(numtype, cvtop, numtype, sx?) + | REF.NULL(reftype) + | REF.FUNC(funcidx) + | REF.IS_NULL + | LOCAL.GET(localidx) + | LOCAL.SET(localidx) + | LOCAL.TEE(localidx) + | GLOBAL.GET(globalidx) + | GLOBAL.SET(globalidx) + | TABLE.GET(tableidx) + | TABLE.SET(tableidx) + | TABLE.SIZE(tableidx) + | TABLE.GROW(tableidx) + | TABLE.FILL(tableidx) + | TABLE.COPY(tableidx, tableidx) + | TABLE.INIT(tableidx, elemidx) + | ELEM.DROP(elemidx) + | MEMORY.SIZE + | MEMORY.GROW + | MEMORY.FILL + | MEMORY.COPY + | MEMORY.INIT(dataidx) + | DATA.DROP(dataidx) + | LOAD(numtype, (n, sx)?, u32, u32) + | STORE(numtype, n?, u32, u32) + | REF.FUNC_ADDR(funcaddr) + | REF.HOST_ADDR(hostaddr) + | CALL_ADDR(funcaddr) + | LABEL_(n, instr*, admininstr*) + | FRAME_(n, frame, admininstr*) + | TRAP +} + +def admininstr_globalinst : globalinst -> admininstr + def {x0 : numtype, x1 : c_numtype} admininstr_globalinst(CONST_val(x0, x1)) = CONST_admininstr(x0, x1) + def {x : reftype} admininstr_globalinst(REF.NULL_val(x)) = REF.NULL_admininstr(x) + def {x : funcaddr} admininstr_globalinst(REF.FUNC_ADDR_val(x)) = REF.FUNC_ADDR_admininstr(x) + def {x : hostaddr} admininstr_globalinst(REF.HOST_ADDR_val(x)) = REF.HOST_ADDR_admininstr(x) + +def admininstr_instr : instr -> admininstr + def admininstr_instr(UNREACHABLE_instr) = UNREACHABLE_admininstr + def admininstr_instr(NOP_instr) = NOP_admininstr + def admininstr_instr(DROP_instr) = DROP_admininstr + def {x : valtype?} admininstr_instr(SELECT_instr(x)) = SELECT_admininstr(x) + def {x0 : blocktype, x1 : instr*} admininstr_instr(BLOCK_instr(x0, x1)) = BLOCK_admininstr(x0, x1) + def {x0 : blocktype, x1 : instr*} admininstr_instr(LOOP_instr(x0, x1)) = LOOP_admininstr(x0, x1) + def {x0 : blocktype, x1 : instr*, x2 : instr*} admininstr_instr(IF_instr(x0, x1, x2)) = IF_admininstr(x0, x1, x2) + def {x : labelidx} admininstr_instr(BR_instr(x)) = BR_admininstr(x) + def {x : labelidx} admininstr_instr(BR_IF_instr(x)) = BR_IF_admininstr(x) + def {x0 : labelidx*, x1 : labelidx} admininstr_instr(BR_TABLE_instr(x0, x1)) = BR_TABLE_admininstr(x0, x1) + def {x : funcidx} admininstr_instr(CALL_instr(x)) = CALL_admininstr(x) + def {x0 : tableidx, x1 : functype} admininstr_instr(CALL_INDIRECT_instr(x0, x1)) = CALL_INDIRECT_admininstr(x0, x1) + def admininstr_instr(RETURN_instr) = RETURN_admininstr + def {x0 : numtype, x1 : c_numtype} admininstr_instr(CONST_instr(x0, x1)) = CONST_admininstr(x0, x1) + def {x0 : numtype, x1 : unop_numtype} admininstr_instr(UNOP_instr(x0, x1)) = UNOP_admininstr(x0, x1) + def {x0 : numtype, x1 : binop_numtype} admininstr_instr(BINOP_instr(x0, x1)) = BINOP_admininstr(x0, x1) + def {x0 : numtype, x1 : testop_numtype} admininstr_instr(TESTOP_instr(x0, x1)) = TESTOP_admininstr(x0, x1) + def {x0 : numtype, x1 : relop_numtype} admininstr_instr(RELOP_instr(x0, x1)) = RELOP_admininstr(x0, x1) + def {x0 : numtype, x1 : n} admininstr_instr(EXTEND_instr(x0, x1)) = EXTEND_admininstr(x0, x1) + def {x0 : numtype, x1 : cvtop, x2 : numtype, x3 : sx?} admininstr_instr(CVTOP_instr(x0, x1, x2, x3)) = CVTOP_admininstr(x0, x1, x2, x3) + def {x : reftype} admininstr_instr(REF.NULL_instr(x)) = REF.NULL_admininstr(x) + def {x : funcidx} admininstr_instr(REF.FUNC_instr(x)) = REF.FUNC_admininstr(x) + def admininstr_instr(REF.IS_NULL_instr) = REF.IS_NULL_admininstr + def {x : localidx} admininstr_instr(LOCAL.GET_instr(x)) = LOCAL.GET_admininstr(x) + def {x : localidx} admininstr_instr(LOCAL.SET_instr(x)) = LOCAL.SET_admininstr(x) + def {x : localidx} admininstr_instr(LOCAL.TEE_instr(x)) = LOCAL.TEE_admininstr(x) + def {x : globalidx} admininstr_instr(GLOBAL.GET_instr(x)) = GLOBAL.GET_admininstr(x) + def {x : globalidx} admininstr_instr(GLOBAL.SET_instr(x)) = GLOBAL.SET_admininstr(x) + def {x : tableidx} admininstr_instr(TABLE.GET_instr(x)) = TABLE.GET_admininstr(x) + def {x : tableidx} admininstr_instr(TABLE.SET_instr(x)) = TABLE.SET_admininstr(x) + def {x : tableidx} admininstr_instr(TABLE.SIZE_instr(x)) = TABLE.SIZE_admininstr(x) + def {x : tableidx} admininstr_instr(TABLE.GROW_instr(x)) = TABLE.GROW_admininstr(x) + def {x : tableidx} admininstr_instr(TABLE.FILL_instr(x)) = TABLE.FILL_admininstr(x) + def {x0 : tableidx, x1 : tableidx} admininstr_instr(TABLE.COPY_instr(x0, x1)) = TABLE.COPY_admininstr(x0, x1) + def {x0 : tableidx, x1 : elemidx} admininstr_instr(TABLE.INIT_instr(x0, x1)) = TABLE.INIT_admininstr(x0, x1) + def {x : elemidx} admininstr_instr(ELEM.DROP_instr(x)) = ELEM.DROP_admininstr(x) + def admininstr_instr(MEMORY.SIZE_instr) = MEMORY.SIZE_admininstr + def admininstr_instr(MEMORY.GROW_instr) = MEMORY.GROW_admininstr + def admininstr_instr(MEMORY.FILL_instr) = MEMORY.FILL_admininstr + def admininstr_instr(MEMORY.COPY_instr) = MEMORY.COPY_admininstr + def {x : dataidx} admininstr_instr(MEMORY.INIT_instr(x)) = MEMORY.INIT_admininstr(x) + def {x : dataidx} admininstr_instr(DATA.DROP_instr(x)) = DATA.DROP_admininstr(x) + def {x0 : numtype, x1 : (n, sx)?, x2 : u32, x3 : u32} admininstr_instr(LOAD_instr(x0, x1, x2, x3)) = LOAD_admininstr(x0, x1, x2, x3) + def {x0 : numtype, x1 : n?, x2 : u32, x3 : u32} admininstr_instr(STORE_instr(x0, x1, x2, x3)) = STORE_admininstr(x0, x1, x2, x3) + +def admininstr_ref : ref -> admininstr + def {x : reftype} admininstr_ref(REF.NULL_ref(x)) = REF.NULL_admininstr(x) + def {x : funcaddr} admininstr_ref(REF.FUNC_ADDR_ref(x)) = REF.FUNC_ADDR_admininstr(x) + def {x : hostaddr} admininstr_ref(REF.HOST_ADDR_ref(x)) = REF.HOST_ADDR_admininstr(x) + +def admininstr_val : val -> admininstr + def {x0 : numtype, x1 : c_numtype} admininstr_val(CONST_val(x0, x1)) = CONST_admininstr(x0, x1) + def {x : reftype} admininstr_val(REF.NULL_val(x)) = REF.NULL_admininstr(x) + def {x : funcaddr} admininstr_val(REF.FUNC_ADDR_val(x)) = REF.FUNC_ADDR_admininstr(x) + def {x : hostaddr} admininstr_val(REF.HOST_ADDR_val(x)) = REF.HOST_ADDR_admininstr(x) + +;; 4-runtime.watsup:84.1-84.62 +syntax config = `%;%*`(state, admininstr*) + +;; 4-runtime.watsup:102.1-102.59 +def funcaddr : state -> funcaddr* + ;; 4-runtime.watsup:103.1-103.38 + def {f : frame, s : store} funcaddr(`%;%`(s, f)) = f.MODULE_frame.FUNC_moduleinst + +;; 4-runtime.watsup:105.1-105.52 +def funcinst : state -> funcinst* + ;; 4-runtime.watsup:106.1-106.31 + def {f : frame, s : store} funcinst(`%;%`(s, f)) = s.FUNC_store + +;; 4-runtime.watsup:108.1-108.67 +def func : (state, funcidx) -> funcinst + ;; 4-runtime.watsup:116.1-116.48 + def {f : frame, s : store, x : idx} func(`%;%`(s, f), x) = s.FUNC_store[f.MODULE_frame.FUNC_moduleinst[x]] + +;; 4-runtime.watsup:109.1-109.69 +def global : (state, globalidx) -> globalinst + ;; 4-runtime.watsup:117.1-117.54 + def {f : frame, s : store, x : idx} global(`%;%`(s, f), x) = s.GLOBAL_store[f.MODULE_frame.GLOBAL_moduleinst[x]] + +;; 4-runtime.watsup:110.1-110.68 +def table : (state, tableidx) -> tableinst + ;; 4-runtime.watsup:118.1-118.51 + def {f : frame, s : store, x : idx} table(`%;%`(s, f), x) = s.TABLE_store[f.MODULE_frame.TABLE_moduleinst[x]] + +;; 4-runtime.watsup:111.1-111.66 +def mem : (state, memidx) -> meminst + ;; 4-runtime.watsup:119.1-119.45 + def {f : frame, s : store, x : idx} mem(`%;%`(s, f), x) = s.MEM_store[f.MODULE_frame.MEM_moduleinst[x]] + +;; 4-runtime.watsup:112.1-112.67 +def elem : (state, tableidx) -> eleminst + ;; 4-runtime.watsup:120.1-120.48 + def {f : frame, s : store, x : idx} elem(`%;%`(s, f), x) = s.ELEM_store[f.MODULE_frame.ELEM_moduleinst[x]] + +;; 4-runtime.watsup:113.1-113.67 +def data : (state, dataidx) -> datainst + ;; 4-runtime.watsup:121.1-121.48 + def {f : frame, s : store, x : idx} data(`%;%`(s, f), x) = s.DATA_store[f.MODULE_frame.DATA_moduleinst[x]] + +;; 4-runtime.watsup:114.1-114.68 +def local : (state, localidx) -> val + ;; 4-runtime.watsup:122.1-122.35 + def {f : frame, s : store, x : idx} local(`%;%`(s, f), x) = f.LOCAL_frame[x] + +;; 4-runtime.watsup:125.1-125.78 +def with_local : (state, localidx, val) -> state + ;; 4-runtime.watsup:134.1-134.52 + def {f : frame, s : store, v : val, x : idx} with_local(`%;%`(s, f), x, v) = `%;%`(s, f[LOCAL_frame[x] = v]) + +;; 4-runtime.watsup:126.1-126.79 +def with_global : (state, globalidx, val) -> state + ;; 4-runtime.watsup:135.1-135.71 + def {f : frame, s : store, v : val, x : idx} with_global(`%;%`(s, f), x, v) = `%;%`(s[GLOBAL_store[f.MODULE_frame.GLOBAL_moduleinst[x]] = v], f) + +;; 4-runtime.watsup:127.1-127.83 +def with_table : (state, tableidx, nat, ref) -> state + ;; 4-runtime.watsup:136.1-136.74 + def {f : frame, i : nat, r : ref, s : store, x : idx} with_table(`%;%`(s, f), x, i, r) = `%;%`(s[TABLE_store[f.MODULE_frame.TABLE_moduleinst[x]][i] = r], f) + +;; 4-runtime.watsup:128.1-128.80 +def with_tableext : (state, tableidx, ref*) -> state + ;; 4-runtime.watsup:137.1-137.75 + def {f : frame, r* : ref*, s : store, x : idx} with_tableext(`%;%`(s, f), x, r*{r}) = `%;%`(s[TABLE_store[f.MODULE_frame.TABLE_moduleinst[x]] =.. r*{r}], f) + +;; 4-runtime.watsup:129.1-129.90 +def with_mem : (state, tableidx, nat, nat, byte*) -> state + ;; 4-runtime.watsup:138.1-138.77 + def {b* : byte*, f : frame, i : nat, j : nat, s : store, x : idx} with_mem(`%;%`(s, f), x, i, j, b*{b}) = `%;%`(s[MEM_store[f.MODULE_frame.MEM_moduleinst[x]][i : j] = b*{b}], f) + +;; 4-runtime.watsup:130.1-130.78 +def with_memext : (state, tableidx, byte*) -> state + ;; 4-runtime.watsup:139.1-139.69 + def {b* : byte*, f : frame, s : store, x : idx} with_memext(`%;%`(s, f), x, b*{b}) = `%;%`(s[MEM_store[f.MODULE_frame.MEM_moduleinst[x]] =.. b*{b}], f) + +;; 4-runtime.watsup:131.1-131.77 +def with_elem : (state, elemidx, ref*) -> state + ;; 4-runtime.watsup:140.1-140.67 + def {f : frame, r* : ref*, s : store, x : idx} with_elem(`%;%`(s, f), x, r*{r}) = `%;%`(s[ELEM_store[f.MODULE_frame.ELEM_moduleinst[x]] = r*{r}], f) + +;; 4-runtime.watsup:132.1-132.77 +def with_data : (state, dataidx, byte*) -> state + ;; 4-runtime.watsup:141.1-141.67 + def {b* : byte*, f : frame, s : store, x : idx} with_data(`%;%`(s, f), x, b*{b}) = `%;%`(s[DATA_store[f.MODULE_frame.DATA_moduleinst[x]] = b*{b}], f) + +;; 4-runtime.watsup:155.1-158.21 +rec { + +;; 4-runtime.watsup:155.1-158.21 +syntax E = + | _HOLE + | _SEQ(val*, E, instr*) + | LABEL_(n, instr*, E) +} + +;; 5-numerics.watsup:3.1-3.79 +def unop : (unop_numtype, numtype, c_numtype) -> c_numtype* + +;; 5-numerics.watsup:4.1-4.80 +def binop : (binop_numtype, numtype, c_numtype, c_numtype) -> c_numtype* + +;; 5-numerics.watsup:5.1-5.79 +def testop : (testop_numtype, numtype, c_numtype) -> c_numtype + +;; 5-numerics.watsup:6.1-6.80 +def relop : (relop_numtype, numtype, c_numtype, c_numtype) -> c_numtype + +;; 5-numerics.watsup:8.1-8.84 +def ext : (nat, nat, sx, c_numtype) -> c_numtype + +;; 5-numerics.watsup:9.1-9.84 +def cvtop : (numtype, cvtop, numtype, sx?, c_numtype) -> c_numtype* + +;; 5-numerics.watsup:11.1-11.32 +def wrap_ : ((nat, nat), c_numtype) -> nat + +;; 5-numerics.watsup:13.1-13.28 +def bytes_ : (nat, c_numtype) -> byte* + +;; 6-reduction.watsup:159.1-161.15 +relation Step_pure_before_ref.is_null-false: `%`(admininstr*) + ;; 6-reduction.watsup:155.1-157.28 + rule ref.is_null-true {rt : reftype, val : val}: + `%`([$admininstr_val(val) REF.IS_NULL_admininstr]) + -- if (val = REF.NULL_val(rt)) + +;; 6-reduction.watsup:4.1-4.63 +relation Step_pure: `%*~>%*`(admininstr*, admininstr*) + ;; 6-reduction.watsup:16.1-17.24 + rule unreachable: + `%*~>%*`([UNREACHABLE_admininstr], [TRAP_admininstr]) + + ;; 6-reduction.watsup:19.1-20.19 + rule nop: + `%*~>%*`([NOP_admininstr], []) + + ;; 6-reduction.watsup:22.1-23.24 + rule drop {val : val}: + `%*~>%*`([$admininstr_val(val) DROP_admininstr], []) + + ;; 6-reduction.watsup:26.1-28.16 + rule select-true {c : c_numtype, t? : valtype?, val_1 : val, val_2 : val}: + `%*~>%*`([$admininstr_val(val_1) $admininstr_val(val_2) CONST_admininstr(I32_numtype, c) SELECT_admininstr(t?{t})], [$admininstr_val(val_1)]) + -- if (c =/= 0) + + ;; 6-reduction.watsup:30.1-32.14 + rule select-false {c : c_numtype, t? : valtype?, val_1 : val, val_2 : val}: + `%*~>%*`([$admininstr_val(val_1) $admininstr_val(val_2) CONST_admininstr(I32_numtype, c) SELECT_admininstr(t?{t})], [$admininstr_val(val_2)]) + -- if (c = 0) + + ;; 6-reduction.watsup:35.1-37.28 + rule block {bt : blocktype, instr* : instr*, k : nat, n : n, t_1^k : valtype^k, t_2^n : valtype^n, val^k : val^k}: + `%*~>%*`($admininstr_val(val)^k{val} :: [BLOCK_admininstr(bt, instr*{instr})], [LABEL__admininstr(n, [], $admininstr_val(val)^k{val} :: $admininstr_instr(instr)*{instr})]) + -- if (bt = `%->%`(t_1^k{t_1}, t_2^n{t_2})) + + ;; 6-reduction.watsup:39.1-41.28 + rule loop {bt : blocktype, instr* : instr*, k : nat, n : n, t_1^k : valtype^k, t_2^n : valtype^n, val^k : val^k}: + `%*~>%*`($admininstr_val(val)^k{val} :: [LOOP_admininstr(bt, instr*{instr})], [LABEL__admininstr(k, [LOOP_instr(bt, instr*{instr})], $admininstr_val(val)^k{val} :: $admininstr_instr(instr)*{instr})]) + -- if (bt = `%->%`(t_1^k{t_1}, t_2^n{t_2})) + + ;; 6-reduction.watsup:43.1-45.16 + rule if-true {bt : blocktype, c : c_numtype, instr_1* : instr*, instr_2* : instr*}: + `%*~>%*`([CONST_admininstr(I32_numtype, c) IF_admininstr(bt, instr_1*{instr_1}, instr_2*{instr_2})], [BLOCK_admininstr(bt, instr_1*{instr_1})]) + -- if (c =/= 0) + + ;; 6-reduction.watsup:47.1-49.14 + rule if-false {bt : blocktype, c : c_numtype, instr_1* : instr*, instr_2* : instr*}: + `%*~>%*`([CONST_admininstr(I32_numtype, c) IF_admininstr(bt, instr_1*{instr_1}, instr_2*{instr_2})], [BLOCK_admininstr(bt, instr_2*{instr_2})]) + -- if (c = 0) + + ;; 6-reduction.watsup:52.1-53.38 + rule label-vals {instr* : instr*, n : n, val* : val*}: + `%*~>%*`([LABEL__admininstr(n, instr*{instr}, $admininstr_val(val)*{val})], $admininstr_val(val)*{val}) + + ;; 6-reduction.watsup:57.1-58.69 + rule br-zero {instr* : instr*, instr'* : instr*, n : n, val^n : val^n, val'* : val*}: + `%*~>%*`([LABEL__admininstr(n, instr'*{instr'}, $admininstr_val(val')*{val'} :: $admininstr_val(val)^n{val} :: [BR_admininstr(0)] :: $admininstr_instr(instr)*{instr})], $admininstr_val(val)^n{val} :: $admininstr_instr(instr')*{instr'}) + + ;; 6-reduction.watsup:60.1-61.65 + rule br-succ {instr* : instr*, instr'* : instr*, l : labelidx, n : n, val* : val*}: + `%*~>%*`([LABEL__admininstr(n, instr'*{instr'}, $admininstr_val(val)*{val} :: [BR_admininstr(l + 1)] :: $admininstr_instr(instr)*{instr})], $admininstr_val(val)*{val} :: [BR_admininstr(l)]) + + ;; 6-reduction.watsup:64.1-66.16 + rule br_if-true {c : c_numtype, l : labelidx}: + `%*~>%*`([CONST_admininstr(I32_numtype, c) BR_IF_admininstr(l)], [BR_admininstr(l)]) + -- if (c =/= 0) + + ;; 6-reduction.watsup:68.1-70.14 + rule br_if-false {c : c_numtype, l : labelidx}: + `%*~>%*`([CONST_admininstr(I32_numtype, c) BR_IF_admininstr(l)], []) + -- if (c = 0) + + ;; 6-reduction.watsup:73.1-75.17 + rule br_table-lt {i : nat, l* : labelidx*, l' : labelidx}: + `%*~>%*`([CONST_admininstr(I32_numtype, i) BR_TABLE_admininstr(l*{l}, l')], [BR_admininstr(l*{l}[i])]) + -- if (i < |l*{l}|) + + ;; 6-reduction.watsup:77.1-79.18 + rule br_table-ge {i : nat, l* : labelidx*, l' : labelidx}: + `%*~>%*`([CONST_admininstr(I32_numtype, i) BR_TABLE_admininstr(l*{l}, l')], [BR_admininstr(l')]) + -- if (i >= |l*{l}|) + + ;; 6-reduction.watsup:101.1-102.35 + rule frame-vals {f : frame, n : n, val^n : val^n}: + `%*~>%*`([FRAME__admininstr(n, f, $admininstr_val(val)^n{val})], $admininstr_val(val)^n{val}) + + ;; 6-reduction.watsup:104.1-105.55 + rule return-frame {f : frame, instr* : instr*, n : n, val^n : val^n, val'* : val*}: + `%*~>%*`([FRAME__admininstr(n, f, $admininstr_val(val')*{val'} :: $admininstr_val(val)^n{val} :: [RETURN_admininstr] :: $admininstr_instr(instr)*{instr})], $admininstr_val(val)^n{val}) + + ;; 6-reduction.watsup:107.1-108.60 + rule return-label {instr* : instr*, instr'* : instr*, k : nat, val* : val*}: + `%*~>%*`([LABEL__admininstr(k, instr'*{instr'}, $admininstr_val(val)*{val} :: [RETURN_admininstr] :: $admininstr_instr(instr)*{instr})], $admininstr_val(val)*{val} :: [RETURN_admininstr]) + + ;; 6-reduction.watsup:111.1-113.33 + rule unop-val {c : c_numtype, c_1 : c_numtype, nt : numtype, unop : unop_numtype}: + `%*~>%*`([CONST_admininstr(nt, c_1) UNOP_admininstr(nt, unop)], [CONST_admininstr(nt, c)]) + -- if ($unop(unop, nt, c_1) = [c]) + + ;; 6-reduction.watsup:115.1-117.39 + rule unop-trap {c_1 : c_numtype, nt : numtype, unop : unop_numtype}: + `%*~>%*`([CONST_admininstr(nt, c_1) UNOP_admininstr(nt, unop)], [TRAP_admininstr]) + -- if ($unop(unop, nt, c_1) = []) + + ;; 6-reduction.watsup:120.1-122.40 + rule binop-val {binop : binop_numtype, c : c_numtype, c_1 : c_numtype, c_2 : c_numtype, nt : numtype}: + `%*~>%*`([CONST_admininstr(nt, c_1) CONST_admininstr(nt, c_2) BINOP_admininstr(nt, binop)], [CONST_admininstr(nt, c)]) + -- if ($binop(binop, nt, c_1, c_2) = [c]) + + ;; 6-reduction.watsup:124.1-126.46 + rule binop-trap {binop : binop_numtype, c_1 : c_numtype, c_2 : c_numtype, nt : numtype}: + `%*~>%*`([CONST_admininstr(nt, c_1) CONST_admininstr(nt, c_2) BINOP_admininstr(nt, binop)], [TRAP_admininstr]) + -- if ($binop(binop, nt, c_1, c_2) = []) + + ;; 6-reduction.watsup:129.1-131.37 + rule testop {c : c_numtype, c_1 : c_numtype, nt : numtype, testop : testop_numtype}: + `%*~>%*`([CONST_admininstr(nt, c_1) TESTOP_admininstr(nt, testop)], [CONST_admininstr(I32_numtype, c)]) + -- if (c = $testop(testop, nt, c_1)) + + ;; 6-reduction.watsup:133.1-135.40 + rule relop {c : c_numtype, c_1 : c_numtype, c_2 : c_numtype, nt : numtype, relop : relop_numtype}: + `%*~>%*`([CONST_admininstr(nt, c_1) CONST_admininstr(nt, c_2) RELOP_admininstr(nt, relop)], [CONST_admininstr(I32_numtype, c)]) + -- if (c = $relop(relop, nt, c_1, c_2)) + + ;; 6-reduction.watsup:138.1-139.70 + rule extend {c : c_numtype, n : n, nt : numtype, o0 : nat}: + `%*~>%*`([CONST_admininstr(nt, c) EXTEND_admininstr(nt, n)], [CONST_admininstr(nt, $ext(n, o0, S_sx, c))]) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + + ;; 6-reduction.watsup:142.1-144.48 + rule cvtop-val {c : c_numtype, c_1 : c_numtype, cvtop : cvtop, nt_1 : numtype, nt_2 : numtype, sx? : sx?}: + `%*~>%*`([CONST_admininstr(nt_1, c_1) CVTOP_admininstr(nt_2, cvtop, nt_1, sx?{sx})], [CONST_admininstr(nt_2, c)]) + -- if ($cvtop(nt_1, cvtop, nt_2, sx?{sx}, c_1) = [c]) + + ;; 6-reduction.watsup:146.1-148.54 + rule cvtop-trap {c_1 : c_numtype, cvtop : cvtop, nt_1 : numtype, nt_2 : numtype, sx? : sx?}: + `%*~>%*`([CONST_admininstr(nt_1, c_1) CVTOP_admininstr(nt_2, cvtop, nt_1, sx?{sx})], [TRAP_admininstr]) + -- if ($cvtop(nt_1, cvtop, nt_2, sx?{sx}, c_1) = []) + + ;; 6-reduction.watsup:155.1-157.28 + rule ref.is_null-true {rt : reftype, val : val}: + `%*~>%*`([$admininstr_val(val) REF.IS_NULL_admininstr], [CONST_admininstr(I32_numtype, 1)]) + -- if (val = REF.NULL_val(rt)) + + ;; 6-reduction.watsup:159.1-161.15 + rule ref.is_null-false {val : val}: + `%*~>%*`([$admininstr_val(val) REF.IS_NULL_admininstr], [CONST_admininstr(I32_numtype, 0)]) + -- unless Step_pure_before_ref.is_null-false: `%`([$admininstr_val(val) REF.IS_NULL_admininstr]) + + ;; 6-reduction.watsup:170.1-171.47 + rule local.tee {val : val, x : idx}: + `%*~>%*`([$admininstr_val(val) LOCAL.TEE_admininstr(x)], [$admininstr_val(val) $admininstr_val(val) LOCAL.SET_admininstr(x)]) + +;; 6-reduction.watsup:91.1-93.15 +relation Step_read_before_call_indirect-trap: `%`(config) + ;; 6-reduction.watsup:85.1-89.17 + rule call_indirect-call {a : addr, ft : functype, ft' : functype, i : nat, instr* : instr*, m : moduleinst, t* : valtype*, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CALL_INDIRECT_admininstr(x, ft)])) + -- if (i < |$table(z, x)|) + -- if (a < |$funcinst(z)|) + -- if ($table(z, x)[i] = REF.FUNC_ADDR_ref(a)) + -- if ($funcinst(z)[a] = `%;%`(m, `FUNC%%*%`(ft', t*{t}, instr*{instr}))) + -- if (ft = ft') + +;; 6-reduction.watsup:214.1-217.14 +relation Step_read_before_table.fill-zero: `%`(config) + ;; 6-reduction.watsup:210.1-212.34 + rule table.fill-trap {i : nat, n : n, val : val, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + -- if ((i + n) > |$table(z, x)|) + +;; 6-reduction.watsup:219.1-223.15 +relation Step_read_before_table.fill-succ: `%`(config) + ;; 6-reduction.watsup:214.1-217.14 + rule table.fill-zero {i : nat, n : n, val : val, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + -- unless Step_read_before_table.fill-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + -- if (n = 0) + + ;; 6-reduction.watsup:210.1-212.34 + rule table.fill-trap {i : nat, n : n, val : val, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + -- if ((i + n) > |$table(z, x)|) + +;; 6-reduction.watsup:230.1-233.14 +relation Step_read_before_table.copy-zero: `%`(config) + ;; 6-reduction.watsup:226.1-228.63 + rule table.copy-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (((i + n) > |$table(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:235.1-240.15 +relation Step_read_before_table.copy-le: `%`(config) + ;; 6-reduction.watsup:230.1-233.14 + rule table.copy-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- unless Step_read_before_table.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (n = 0) + + ;; 6-reduction.watsup:226.1-228.63 + rule table.copy-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (((i + n) > |$table(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:242.1-246.15 +relation Step_read_before_table.copy-gt: `%`(config) + ;; 6-reduction.watsup:235.1-240.15 + rule table.copy-le {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- unless Step_read_before_table.copy-le: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (j <= i) + + ;; 6-reduction.watsup:230.1-233.14 + rule table.copy-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- unless Step_read_before_table.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (n = 0) + + ;; 6-reduction.watsup:226.1-228.63 + rule table.copy-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (((i + n) > |$table(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:253.1-256.14 +relation Step_read_before_table.init-zero: `%`(config) + ;; 6-reduction.watsup:249.1-251.62 + rule table.init-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + -- if (((i + n) > |$elem(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:258.1-262.15 +relation Step_read_before_table.init-succ: `%`(config) + ;; 6-reduction.watsup:253.1-256.14 + rule table.init-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + -- unless Step_read_before_table.init-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + -- if (n = 0) + + ;; 6-reduction.watsup:249.1-251.62 + rule table.init-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + -- if (((i + n) > |$elem(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:319.1-322.14 +relation Step_read_before_memory.fill-zero: `%`(config) + ;; 6-reduction.watsup:315.1-317.32 + rule memory.fill-trap {i : nat, n : n, val : val, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + -- if ((i + n) > |$mem(z, 0)|) + +;; 6-reduction.watsup:324.1-328.15 +relation Step_read_before_memory.fill-succ: `%`(config) + ;; 6-reduction.watsup:319.1-322.14 + rule memory.fill-zero {i : nat, n : n, val : val, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + -- unless Step_read_before_memory.fill-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + -- if (n = 0) + + ;; 6-reduction.watsup:315.1-317.32 + rule memory.fill-trap {i : nat, n : n, val : val, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + -- if ((i + n) > |$mem(z, 0)|) + +;; 6-reduction.watsup:335.1-338.14 +relation Step_read_before_memory.copy-zero: `%`(config) + ;; 6-reduction.watsup:331.1-333.59 + rule memory.copy-trap {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (((i + n) > |$mem(z, 0)|) \/ ((j + n) > |$mem(z, 0)|)) + +;; 6-reduction.watsup:340.1-345.15 +relation Step_read_before_memory.copy-le: `%`(config) + ;; 6-reduction.watsup:335.1-338.14 + rule memory.copy-zero {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- unless Step_read_before_memory.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (n = 0) + + ;; 6-reduction.watsup:331.1-333.59 + rule memory.copy-trap {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (((i + n) > |$mem(z, 0)|) \/ ((j + n) > |$mem(z, 0)|)) + +;; 6-reduction.watsup:347.1-351.15 +relation Step_read_before_memory.copy-gt: `%`(config) + ;; 6-reduction.watsup:340.1-345.15 + rule memory.copy-le {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- unless Step_read_before_memory.copy-le: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (j <= i) + + ;; 6-reduction.watsup:335.1-338.14 + rule memory.copy-zero {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- unless Step_read_before_memory.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (n = 0) + + ;; 6-reduction.watsup:331.1-333.59 + rule memory.copy-trap {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (((i + n) > |$mem(z, 0)|) \/ ((j + n) > |$mem(z, 0)|)) + +;; 6-reduction.watsup:358.1-361.14 +relation Step_read_before_memory.init-zero: `%`(config) + ;; 6-reduction.watsup:354.1-356.60 + rule memory.init-trap {i : nat, j : nat, n : n, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + -- if (((i + n) > |$data(z, x)|) \/ ((j + n) > |$mem(z, 0)|)) + +;; 6-reduction.watsup:363.1-367.15 +relation Step_read_before_memory.init-succ: `%`(config) + ;; 6-reduction.watsup:358.1-361.14 + rule memory.init-zero {i : nat, j : nat, n : n, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + -- unless Step_read_before_memory.init-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + -- if (n = 0) + + ;; 6-reduction.watsup:354.1-356.60 + rule memory.init-trap {i : nat, j : nat, n : n, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + -- if (((i + n) > |$data(z, x)|) \/ ((j + n) > |$mem(z, 0)|)) + +;; 6-reduction.watsup:5.1-5.63 +relation Step_read: `%~>%*`(config, admininstr*) + ;; 6-reduction.watsup:82.1-83.47 + rule call {x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CALL_admininstr(x)]), [CALL_ADDR_admininstr($funcaddr(z)[x])]) + -- if (x < |$funcaddr(z)|) + + ;; 6-reduction.watsup:85.1-89.17 + rule call_indirect-call {a : addr, ft : functype, ft' : functype, i : nat, instr* : instr*, m : moduleinst, t* : valtype*, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CALL_INDIRECT_admininstr(x, ft)]), [CALL_ADDR_admininstr(a)]) + -- if (i < |$table(z, x)|) + -- if (a < |$funcinst(z)|) + -- if ($table(z, x)[i] = REF.FUNC_ADDR_ref(a)) + -- if ($funcinst(z)[a] = `%;%`(m, `FUNC%%*%`(ft', t*{t}, instr*{instr}))) + -- if (ft = ft') + + ;; 6-reduction.watsup:91.1-93.15 + rule call_indirect-trap {ft : functype, i : nat, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CALL_INDIRECT_admininstr(x, ft)]), [TRAP_admininstr]) + -- unless Step_read_before_call_indirect-trap: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CALL_INDIRECT_admininstr(x, ft)])) + + ;; 6-reduction.watsup:95.1-98.52 + rule call_addr {a : addr, f : frame, instr* : instr*, k : nat, m : moduleinst, n : n, t* : valtype*, t_1^k : valtype^k, t_2^n : valtype^n, val^k : val^k, z : state, o0* : val*}: + `%~>%*`(`%;%*`(z, $admininstr_val(val)^k{val} :: [CALL_ADDR_admininstr(a)]), [FRAME__admininstr(n, f, [LABEL__admininstr(n, [], $admininstr_instr(instr)*{instr})])]) + -- if (|t*{t}| = |o0*{o0}|) + -- if (a < |$funcinst(z)|) + -- (if ($default_(t) = ?(o0)))*{t o0} + -- if ($funcinst(z)[a] = `%;%`(m, `FUNC%%*%`(`%->%`(t_1^k{t_1}, t_2^n{t_2}), t*{t}, instr*{instr}))) + -- if (f = {LOCAL val^k{val} :: o0*{o0}, MODULE m}) + + ;; 6-reduction.watsup:151.1-152.53 + rule ref.func {x : idx, z : state}: + `%~>%*`(`%;%*`(z, [REF.FUNC_admininstr(x)]), [REF.FUNC_ADDR_admininstr($funcaddr(z)[x])]) + -- if (x < |$funcaddr(z)|) + + ;; 6-reduction.watsup:164.1-165.37 + rule local.get {x : idx, z : state}: + `%~>%*`(`%;%*`(z, [LOCAL.GET_admininstr(x)]), [$admininstr_val($local(z, x))]) + + ;; 6-reduction.watsup:174.1-175.39 + rule global.get {x : idx, z : state}: + `%~>%*`(`%;%*`(z, [GLOBAL.GET_admininstr(x)]), [$admininstr_globalinst($global(z, x))]) + + ;; 6-reduction.watsup:181.1-183.28 + rule table.get-trap {i : nat, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) TABLE.GET_admininstr(x)]), [TRAP_admininstr]) + -- if (i >= |$table(z, x)|) + + ;; 6-reduction.watsup:185.1-187.27 + rule table.get-val {i : nat, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) TABLE.GET_admininstr(x)]), [$admininstr_ref($table(z, x)[i])]) + -- if (i < |$table(z, x)|) + + ;; 6-reduction.watsup:198.1-200.27 + rule table.size {n : n, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [TABLE.SIZE_admininstr(x)]), [CONST_admininstr(I32_numtype, n)]) + -- if (|$table(z, x)| = n) + + ;; 6-reduction.watsup:210.1-212.34 + rule table.fill-trap {i : nat, n : n, val : val, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)]), [TRAP_admininstr]) + -- if ((i + n) > |$table(z, x)|) + + ;; 6-reduction.watsup:214.1-217.14 + rule table.fill-zero {i : nat, n : n, val : val, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)]), []) + -- unless Step_read_before_table.fill-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + -- if (n = 0) + + ;; 6-reduction.watsup:219.1-223.15 + rule table.fill-succ {i : nat, n : n, val : val, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)]), [CONST_admininstr(I32_numtype, i) $admininstr_val(val) TABLE.SET_admininstr(x) CONST_admininstr(I32_numtype, (i + 1)) $admininstr_val(val) CONST_admininstr(I32_numtype, (n - 1)) TABLE.FILL_admininstr(x)]) + -- unless Step_read_before_table.fill-succ: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + + ;; 6-reduction.watsup:226.1-228.63 + rule table.copy-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)]), [TRAP_admininstr]) + -- if (((i + n) > |$table(z, y)|) \/ ((j + n) > |$table(z, x)|)) + + ;; 6-reduction.watsup:230.1-233.14 + rule table.copy-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)]), []) + -- unless Step_read_before_table.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (n = 0) + + ;; 6-reduction.watsup:235.1-240.15 + rule table.copy-le {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)]), [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) TABLE.GET_admininstr(y) TABLE.SET_admininstr(x) CONST_admininstr(I32_numtype, (j + 1)) CONST_admininstr(I32_numtype, (i + 1)) CONST_admininstr(I32_numtype, (n - 1)) TABLE.COPY_admininstr(x, y)]) + -- unless Step_read_before_table.copy-le: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (j <= i) + + ;; 6-reduction.watsup:242.1-246.15 + rule table.copy-gt {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)]), [CONST_admininstr(I32_numtype, ((j + n) - 1)) CONST_admininstr(I32_numtype, ((i + n) - 1)) TABLE.GET_admininstr(y) TABLE.SET_admininstr(x) CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, (n - 1)) TABLE.COPY_admininstr(x, y)]) + -- unless Step_read_before_table.copy-gt: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + + ;; 6-reduction.watsup:249.1-251.62 + rule table.init-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)]), [TRAP_admininstr]) + -- if (((i + n) > |$elem(z, y)|) \/ ((j + n) > |$table(z, x)|)) + + ;; 6-reduction.watsup:253.1-256.14 + rule table.init-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)]), []) + -- unless Step_read_before_table.init-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + -- if (n = 0) + + ;; 6-reduction.watsup:258.1-262.15 + rule table.init-succ {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)]), [CONST_admininstr(I32_numtype, j) $admininstr_ref($elem(z, y)[i]) TABLE.SET_admininstr(x) CONST_admininstr(I32_numtype, (j + 1)) CONST_admininstr(I32_numtype, (i + 1)) CONST_admininstr(I32_numtype, (n - 1)) TABLE.INIT_admininstr(x, y)]) + -- if (i < |$elem(z, y)|) + -- unless Step_read_before_table.init-succ: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + + ;; 6-reduction.watsup:269.1-271.48 + rule load-num-trap {i : nat, n_A : n, n_O : n, nt : numtype, z : state, o0 : nat}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) LOAD_admininstr(nt, ?(), n_A, n_O)]), [TRAP_admininstr]) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + -- if (((i + n_O) + (o0 / 8)) > |$mem(z, 0)|) + + ;; 6-reduction.watsup:273.1-275.66 + rule load-num-val {c : c_numtype, i : nat, n_A : n, n_O : n, nt : numtype, z : state, o0 : nat, o1 : nat}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) LOAD_admininstr(nt, ?(), n_A, n_O)]), [CONST_admininstr(nt, c)]) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + -- if ($size($valtype_numtype(nt)) = ?(o1)) + -- if ($bytes_(o0, c) = $mem(z, 0)[(i + n_O) : (o1 / 8)]) + + ;; 6-reduction.watsup:277.1-279.40 + rule load-pack-trap {i : nat, n : n, n_A : n, n_O : n, nt : numtype, sx : sx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) LOAD_admininstr(nt, ?((n, sx)), n_A, n_O)]), [TRAP_admininstr]) + -- if (((i + n_O) + (n / 8)) > |$mem(z, 0)|) + + ;; 6-reduction.watsup:281.1-283.50 + rule load-pack-val {c : c_numtype, i : nat, n : n, n_A : n, n_O : n, nt : numtype, sx : sx, z : state, o0 : nat}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) LOAD_admininstr(nt, ?((n, sx)), n_A, n_O)]), [CONST_admininstr(nt, $ext(n, o0, sx, c))]) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + -- if ($bytes_(n, c) = $mem(z, 0)[(i + n_O) : (n / 8)]) + + ;; 6-reduction.watsup:303.1-305.39 + rule memory.size {n : n, z : state}: + `%~>%*`(`%;%*`(z, [MEMORY.SIZE_admininstr]), [CONST_admininstr(I32_numtype, n)]) + -- if (((n * 64) * $Ki) = |$mem(z, 0)|) + + ;; 6-reduction.watsup:315.1-317.32 + rule memory.fill-trap {i : nat, n : n, val : val, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr]), [TRAP_admininstr]) + -- if ((i + n) > |$mem(z, 0)|) + + ;; 6-reduction.watsup:319.1-322.14 + rule memory.fill-zero {i : nat, n : n, val : val, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr]), []) + -- unless Step_read_before_memory.fill-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + -- if (n = 0) + + ;; 6-reduction.watsup:324.1-328.15 + rule memory.fill-succ {i : nat, n : n, val : val, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr]), [CONST_admininstr(I32_numtype, i) $admininstr_val(val) STORE_admininstr(I32_numtype, ?(8), 0, 0) CONST_admininstr(I32_numtype, (i + 1)) $admininstr_val(val) CONST_admininstr(I32_numtype, (n - 1)) MEMORY.FILL_admininstr]) + -- unless Step_read_before_memory.fill-succ: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + + ;; 6-reduction.watsup:331.1-333.59 + rule memory.copy-trap {i : nat, j : nat, n : n, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr]), [TRAP_admininstr]) + -- if (((i + n) > |$mem(z, 0)|) \/ ((j + n) > |$mem(z, 0)|)) + + ;; 6-reduction.watsup:335.1-338.14 + rule memory.copy-zero {i : nat, j : nat, n : n, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr]), []) + -- unless Step_read_before_memory.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (n = 0) + + ;; 6-reduction.watsup:340.1-345.15 + rule memory.copy-le {i : nat, j : nat, n : n, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr]), [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) LOAD_admininstr(I32_numtype, ?((8, U_sx)), 0, 0) STORE_admininstr(I32_numtype, ?(8), 0, 0) CONST_admininstr(I32_numtype, (j + 1)) CONST_admininstr(I32_numtype, (i + 1)) CONST_admininstr(I32_numtype, (n - 1)) MEMORY.COPY_admininstr]) + -- unless Step_read_before_memory.copy-le: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (j <= i) + + ;; 6-reduction.watsup:347.1-351.15 + rule memory.copy-gt {i : nat, j : nat, n : n, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr]), [CONST_admininstr(I32_numtype, ((j + n) - 1)) CONST_admininstr(I32_numtype, ((i + n) - 1)) LOAD_admininstr(I32_numtype, ?((8, U_sx)), 0, 0) STORE_admininstr(I32_numtype, ?(8), 0, 0) CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, (n - 1)) MEMORY.COPY_admininstr]) + -- unless Step_read_before_memory.copy-gt: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + + ;; 6-reduction.watsup:354.1-356.60 + rule memory.init-trap {i : nat, j : nat, n : n, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)]), [TRAP_admininstr]) + -- if (((i + n) > |$data(z, x)|) \/ ((j + n) > |$mem(z, 0)|)) + + ;; 6-reduction.watsup:358.1-361.14 + rule memory.init-zero {i : nat, j : nat, n : n, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)]), []) + -- unless Step_read_before_memory.init-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + -- if (n = 0) + + ;; 6-reduction.watsup:363.1-367.15 + rule memory.init-succ {i : nat, j : nat, n : n, x : idx, z : state}: + `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)]), [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, $data(z, x)[i]) STORE_admininstr(I32_numtype, ?(8), 0, 0) CONST_admininstr(I32_numtype, (j + 1)) CONST_admininstr(I32_numtype, (i + 1)) CONST_admininstr(I32_numtype, (n - 1)) MEMORY.INIT_admininstr(x)]) + -- if (i < |$data(z, x)|) + -- unless Step_read_before_memory.init-succ: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + +;; 6-reduction.watsup:3.1-3.63 +relation Step: `%~>%`(config, config) + ;; 6-reduction.watsup:7.1-9.34 + rule pure {instr* : instr*, instr'* : instr*, z : state}: + `%~>%`(`%;%*`(z, $admininstr_instr(instr)*{instr}), `%;%*`(z, $admininstr_instr(instr')*{instr'})) + -- Step_pure: `%*~>%*`($admininstr_instr(instr)*{instr}, $admininstr_instr(instr')*{instr'}) + + ;; 6-reduction.watsup:11.1-13.37 + rule read {instr* : instr*, instr'* : instr*, z : state}: + `%~>%`(`%;%*`(z, $admininstr_instr(instr)*{instr}), `%;%*`(z, $admininstr_instr(instr')*{instr'})) + -- Step_read: `%~>%*`(`%;%*`(z, $admininstr_instr(instr)*{instr}), $admininstr_instr(instr')*{instr'}) + + ;; 6-reduction.watsup:167.1-168.60 + rule local.set {val : val, x : idx, z : state}: + `%~>%`(`%;%*`(z, [$admininstr_val(val) LOCAL.SET_admininstr(x)]), `%;%*`($with_local(z, x, val), [])) + + ;; 6-reduction.watsup:177.1-178.62 + rule global.set {val : val, x : idx, z : state}: + `%~>%`(`%;%*`(z, [$admininstr_val(val) GLOBAL.SET_admininstr(x)]), `%;%*`($with_global(z, x, val), [])) + + ;; 6-reduction.watsup:189.1-191.28 + rule table.set-trap {i : nat, ref : ref, x : idx, z : state}: + `%~>%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_ref(ref) TABLE.GET_admininstr(x)]), `%;%*`(z, [TRAP_admininstr])) + -- if (i >= |$table(z, x)|) + + ;; 6-reduction.watsup:193.1-195.27 + rule table.set-val {i : nat, ref : ref, x : idx, z : state}: + `%~>%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_ref(ref) TABLE.GET_admininstr(x)]), `%;%*`($with_table(z, x, i, ref), [])) + -- if (i < |$table(z, x)|) + + ;; 6-reduction.watsup:203.1-204.102 + rule table.grow-succeed {n : n, ref : ref, x : idx, z : state}: + `%~>%`(`%;%*`(z, [$admininstr_ref(ref) CONST_admininstr(I32_numtype, n) TABLE.GROW_admininstr(x)]), `%;%*`($with_tableext(z, x, ref^n{}), [CONST_admininstr(I32_numtype, |$table(z, x)|)])) + + ;; 6-reduction.watsup:206.1-207.64 + rule table.grow-fail {n : n, ref : ref, x : idx, z : state}: + `%~>%`(`%;%*`(z, [$admininstr_ref(ref) CONST_admininstr(I32_numtype, n) TABLE.GROW_admininstr(x)]), `%;%*`(z, [CONST_admininstr(I32_numtype, - 1)])) + + ;; 6-reduction.watsup:265.1-266.59 + rule elem.drop {x : idx, z : state}: + `%~>%`(`%;%*`(z, [ELEM.DROP_admininstr(x)]), `%;%*`($with_elem(z, x, []), [])) + + ;; 6-reduction.watsup:286.1-288.48 + rule store-num-trap {c : c_numtype, i : nat, n_A : n, n_O : n, nt : numtype, z : state, o0 : nat}: + `%~>%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CONST_admininstr(nt, c) STORE_admininstr(nt, ?(), n_A, n_O)]), `%;%*`(z, [TRAP_admininstr])) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + -- if (((i + n_O) + (o0 / 8)) > |$mem(z, 0)|) + + ;; 6-reduction.watsup:290.1-292.35 + rule store-num-val {b* : byte*, c : c_numtype, i : nat, n_A : n, n_O : n, nt : numtype, z : state, o0 : nat, o1 : nat}: + `%~>%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CONST_admininstr(nt, c) STORE_admininstr(nt, ?(), n_A, n_O)]), `%;%*`($with_mem(z, 0, (i + n_O), (o0 / 8), b*{b}), [])) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + -- if ($size($valtype_numtype(nt)) = ?(o1)) + -- if (b*{b} = $bytes_(o1, c)) + + ;; 6-reduction.watsup:294.1-296.40 + rule store-pack-trap {c : c_numtype, i : nat, n : n, n_A : n, n_O : n, nt : numtype, z : state}: + `%~>%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CONST_admininstr(nt, c) STORE_admininstr(nt, ?(n), n_A, n_O)]), `%;%*`(z, [TRAP_admininstr])) + -- if (((i + n_O) + (n / 8)) > |$mem(z, 0)|) + + ;; 6-reduction.watsup:298.1-300.50 + rule store-pack-val {b* : byte*, c : c_numtype, i : nat, n : n, n_A : n, n_O : n, nt : numtype, z : state, o0 : nat}: + `%~>%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CONST_admininstr(nt, c) STORE_admininstr(nt, ?(n), n_A, n_O)]), `%;%*`($with_mem(z, 0, (i + n_O), (n / 8), b*{b}), [])) + -- if ($size($valtype_numtype(nt)) = ?(o0)) + -- if (b*{b} = $bytes_(n, $wrap_((o0, n), c))) + + ;; 6-reduction.watsup:308.1-309.117 + rule memory.grow-succeed {n : n, z : state}: + `%~>%`(`%;%*`(z, [CONST_admininstr(I32_numtype, n) MEMORY.GROW_admininstr]), `%;%*`($with_memext(z, 0, 0^((n * 64) * $Ki){}), [CONST_admininstr(I32_numtype, (|$mem(z, 0)| / (64 * $Ki)))])) + + ;; 6-reduction.watsup:311.1-312.59 + rule memory.grow-fail {n : n, z : state}: + `%~>%`(`%;%*`(z, [CONST_admininstr(I32_numtype, n) MEMORY.GROW_admininstr]), `%;%*`(z, [CONST_admininstr(I32_numtype, - 1)])) + + ;; 6-reduction.watsup:370.1-371.59 + rule data.drop {x : idx, z : state}: + `%~>%`(`%;%*`(z, [DATA.DROP_admininstr(x)]), `%;%*`($with_data(z, x, []), [])) + == IL Validation... == Running pass animate Animation failed:if ($funcinst(z)[a] = `%;%`(m, `FUNC%%*%`(ft', t*{t}, instr*{instr}))) @@ -11757,6 +13734,13 @@ def wrap_ : ((nat, nat), c_numtype) -> nat ;; 5-numerics.watsup:13.1-13.28 def bytes_ : (nat, c_numtype) -> byte* +;; 6-reduction.watsup:159.1-161.15 +relation Step_pure_before_ref.is_null-false: `%`(admininstr*) + ;; 6-reduction.watsup:155.1-157.28 + rule ref.is_null-true {rt : reftype, val : val}: + `%`([$admininstr_val(val) REF.IS_NULL_admininstr]) + -- if (val = REF.NULL_val(rt)) + ;; 6-reduction.watsup:4.1-4.63 relation Step_pure: `%*~>%*`(admininstr*, admininstr*) ;; 6-reduction.watsup:16.1-17.24 @@ -11898,12 +13882,181 @@ relation Step_pure: `%*~>%*`(admininstr*, admininstr*) ;; 6-reduction.watsup:159.1-161.15 rule ref.is_null-false {val : val}: `%*~>%*`([$admininstr_val(val) REF.IS_NULL_admininstr], [CONST_admininstr(I32_numtype, 0)]) - -- otherwise + -- unless Step_pure_before_ref.is_null-false: `%`([$admininstr_val(val) REF.IS_NULL_admininstr]) ;; 6-reduction.watsup:170.1-171.47 rule local.tee {val : val, x : idx}: `%*~>%*`([$admininstr_val(val) LOCAL.TEE_admininstr(x)], [$admininstr_val(val) $admininstr_val(val) LOCAL.SET_admininstr(x)]) +;; 6-reduction.watsup:91.1-93.15 +relation Step_read_before_call_indirect-trap: `%`(config) + ;; 6-reduction.watsup:85.1-89.17 + rule call_indirect-call {a : addr, ft : functype, ft' : functype, i : nat, instr* : instr*, m : moduleinst, t* : valtype*, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CALL_INDIRECT_admininstr(x, ft)])) + -- if (i < |$table(z, x)|) + -- if (a < |$funcinst(z)|) + -- if ($table(z, x)[i] = REF.FUNC_ADDR_ref(a)) + -- if ($funcinst(z)[a] = `%;%`(m, `FUNC%%*%`(ft', t*{t}, instr*{instr}))) + -- if (ft = ft') + +;; 6-reduction.watsup:214.1-217.14 +relation Step_read_before_table.fill-zero: `%`(config) + ;; 6-reduction.watsup:210.1-212.34 + rule table.fill-trap {i : nat, n : n, val : val, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + -- if ((i + n) > |$table(z, x)|) + +;; 6-reduction.watsup:219.1-223.15 +relation Step_read_before_table.fill-succ: `%`(config) + ;; 6-reduction.watsup:214.1-217.14 + rule table.fill-zero {i : nat, n : n, val : val, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + -- unless Step_read_before_table.fill-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + -- if (n = 0) + + ;; 6-reduction.watsup:210.1-212.34 + rule table.fill-trap {i : nat, n : n, val : val, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) + -- if ((i + n) > |$table(z, x)|) + +;; 6-reduction.watsup:230.1-233.14 +relation Step_read_before_table.copy-zero: `%`(config) + ;; 6-reduction.watsup:226.1-228.63 + rule table.copy-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (((i + n) > |$table(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:235.1-240.15 +relation Step_read_before_table.copy-le: `%`(config) + ;; 6-reduction.watsup:230.1-233.14 + rule table.copy-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- unless Step_read_before_table.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (n = 0) + + ;; 6-reduction.watsup:226.1-228.63 + rule table.copy-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (((i + n) > |$table(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:242.1-246.15 +relation Step_read_before_table.copy-gt: `%`(config) + ;; 6-reduction.watsup:235.1-240.15 + rule table.copy-le {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- unless Step_read_before_table.copy-le: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (j <= i) + + ;; 6-reduction.watsup:230.1-233.14 + rule table.copy-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- unless Step_read_before_table.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (n = 0) + + ;; 6-reduction.watsup:226.1-228.63 + rule table.copy-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) + -- if (((i + n) > |$table(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:253.1-256.14 +relation Step_read_before_table.init-zero: `%`(config) + ;; 6-reduction.watsup:249.1-251.62 + rule table.init-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + -- if (((i + n) > |$elem(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:258.1-262.15 +relation Step_read_before_table.init-succ: `%`(config) + ;; 6-reduction.watsup:253.1-256.14 + rule table.init-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + -- unless Step_read_before_table.init-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + -- if (n = 0) + + ;; 6-reduction.watsup:249.1-251.62 + rule table.init-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) + -- if (((i + n) > |$elem(z, y)|) \/ ((j + n) > |$table(z, x)|)) + +;; 6-reduction.watsup:319.1-322.14 +relation Step_read_before_memory.fill-zero: `%`(config) + ;; 6-reduction.watsup:315.1-317.32 + rule memory.fill-trap {i : nat, n : n, val : val, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + -- if ((i + n) > |$mem(z, 0)|) + +;; 6-reduction.watsup:324.1-328.15 +relation Step_read_before_memory.fill-succ: `%`(config) + ;; 6-reduction.watsup:319.1-322.14 + rule memory.fill-zero {i : nat, n : n, val : val, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + -- unless Step_read_before_memory.fill-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + -- if (n = 0) + + ;; 6-reduction.watsup:315.1-317.32 + rule memory.fill-trap {i : nat, n : n, val : val, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) + -- if ((i + n) > |$mem(z, 0)|) + +;; 6-reduction.watsup:335.1-338.14 +relation Step_read_before_memory.copy-zero: `%`(config) + ;; 6-reduction.watsup:331.1-333.59 + rule memory.copy-trap {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (((i + n) > |$mem(z, 0)|) \/ ((j + n) > |$mem(z, 0)|)) + +;; 6-reduction.watsup:340.1-345.15 +relation Step_read_before_memory.copy-le: `%`(config) + ;; 6-reduction.watsup:335.1-338.14 + rule memory.copy-zero {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- unless Step_read_before_memory.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (n = 0) + + ;; 6-reduction.watsup:331.1-333.59 + rule memory.copy-trap {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (((i + n) > |$mem(z, 0)|) \/ ((j + n) > |$mem(z, 0)|)) + +;; 6-reduction.watsup:347.1-351.15 +relation Step_read_before_memory.copy-gt: `%`(config) + ;; 6-reduction.watsup:340.1-345.15 + rule memory.copy-le {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- unless Step_read_before_memory.copy-le: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (j <= i) + + ;; 6-reduction.watsup:335.1-338.14 + rule memory.copy-zero {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- unless Step_read_before_memory.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (n = 0) + + ;; 6-reduction.watsup:331.1-333.59 + rule memory.copy-trap {i : nat, j : nat, n : n, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) + -- if (((i + n) > |$mem(z, 0)|) \/ ((j + n) > |$mem(z, 0)|)) + +;; 6-reduction.watsup:358.1-361.14 +relation Step_read_before_memory.init-zero: `%`(config) + ;; 6-reduction.watsup:354.1-356.60 + rule memory.init-trap {i : nat, j : nat, n : n, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + -- if (((i + n) > |$data(z, x)|) \/ ((j + n) > |$mem(z, 0)|)) + +;; 6-reduction.watsup:363.1-367.15 +relation Step_read_before_memory.init-succ: `%`(config) + ;; 6-reduction.watsup:358.1-361.14 + rule memory.init-zero {i : nat, j : nat, n : n, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + -- unless Step_read_before_memory.init-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + -- if (n = 0) + + ;; 6-reduction.watsup:354.1-356.60 + rule memory.init-trap {i : nat, j : nat, n : n, x : idx, z : state}: + `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) + -- if (((i + n) > |$data(z, x)|) \/ ((j + n) > |$mem(z, 0)|)) + ;; 6-reduction.watsup:5.1-5.63 relation Step_read: `%~>%*`(config, admininstr*) ;; 6-reduction.watsup:82.1-83.47 @@ -11923,7 +14076,7 @@ relation Step_read: `%~>%*`(config, admininstr*) ;; 6-reduction.watsup:91.1-93.15 rule call_indirect-trap {ft : functype, i : nat, x : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CALL_INDIRECT_admininstr(x, ft)]), [TRAP_admininstr]) - -- otherwise + -- unless Step_read_before_call_indirect-trap: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) CALL_INDIRECT_admininstr(x, ft)])) ;; 6-reduction.watsup:95.1-98.52 rule call_addr {a : addr, f : frame, instr* : instr*, k : nat, m : moduleinst, n : n, t* : valtype*, t_1^k : valtype^k, t_2^n : valtype^n, val^k : val^k, z : state, o0* : val*}: @@ -11970,13 +14123,13 @@ relation Step_read: `%~>%*`(config, admininstr*) ;; 6-reduction.watsup:214.1-217.14 rule table.fill-zero {i : nat, n : n, val : val, x : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)]), []) - -- otherwise + -- unless Step_read_before_table.fill-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) -- if (n = 0) ;; 6-reduction.watsup:219.1-223.15 rule table.fill-succ {i : nat, n : n, val : val, x : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)]), [CONST_admininstr(I32_numtype, i) $admininstr_val(val) TABLE.SET_admininstr(x) CONST_admininstr(I32_numtype, (i + 1)) $admininstr_val(val) CONST_admininstr(I32_numtype, (n - 1)) TABLE.FILL_admininstr(x)]) - -- otherwise + -- unless Step_read_before_table.fill-succ: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) TABLE.FILL_admininstr(x)])) ;; 6-reduction.watsup:226.1-228.63 rule table.copy-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: @@ -11986,19 +14139,19 @@ relation Step_read: `%~>%*`(config, admininstr*) ;; 6-reduction.watsup:230.1-233.14 rule table.copy-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)]), []) - -- otherwise + -- unless Step_read_before_table.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) -- if (n = 0) ;; 6-reduction.watsup:235.1-240.15 rule table.copy-le {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)]), [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) TABLE.GET_admininstr(y) TABLE.SET_admininstr(x) CONST_admininstr(I32_numtype, (j + 1)) CONST_admininstr(I32_numtype, (i + 1)) CONST_admininstr(I32_numtype, (n - 1)) TABLE.COPY_admininstr(x, y)]) - -- otherwise + -- unless Step_read_before_table.copy-le: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) -- if (j <= i) ;; 6-reduction.watsup:242.1-246.15 rule table.copy-gt {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)]), [CONST_admininstr(I32_numtype, ((j + n) - 1)) CONST_admininstr(I32_numtype, ((i + n) - 1)) TABLE.GET_admininstr(y) TABLE.SET_admininstr(x) CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, (n - 1)) TABLE.COPY_admininstr(x, y)]) - -- otherwise + -- unless Step_read_before_table.copy-gt: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.COPY_admininstr(x, y)])) ;; 6-reduction.watsup:249.1-251.62 rule table.init-trap {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: @@ -12008,14 +14161,14 @@ relation Step_read: `%~>%*`(config, admininstr*) ;; 6-reduction.watsup:253.1-256.14 rule table.init-zero {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)]), []) - -- otherwise + -- unless Step_read_before_table.init-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) -- if (n = 0) ;; 6-reduction.watsup:258.1-262.15 rule table.init-succ {i : nat, j : nat, n : n, x : idx, y : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)]), [CONST_admininstr(I32_numtype, j) $admininstr_ref($elem(z, y)[i]) TABLE.SET_admininstr(x) CONST_admininstr(I32_numtype, (j + 1)) CONST_admininstr(I32_numtype, (i + 1)) CONST_admininstr(I32_numtype, (n - 1)) TABLE.INIT_admininstr(x, y)]) - -- otherwise -- if (i < |$elem(z, y)|) + -- unless Step_read_before_table.init-succ: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) TABLE.INIT_admininstr(x, y)])) ;; 6-reduction.watsup:269.1-271.48 rule load-num-trap {i : nat, n_A : n, n_O : n, nt : numtype, z : state, o0 : nat}: @@ -12054,13 +14207,13 @@ relation Step_read: `%~>%*`(config, admininstr*) ;; 6-reduction.watsup:319.1-322.14 rule memory.fill-zero {i : nat, n : n, val : val, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr]), []) - -- otherwise + -- unless Step_read_before_memory.fill-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) -- if (n = 0) ;; 6-reduction.watsup:324.1-328.15 rule memory.fill-succ {i : nat, n : n, val : val, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr]), [CONST_admininstr(I32_numtype, i) $admininstr_val(val) STORE_admininstr(I32_numtype, ?(8), 0, 0) CONST_admininstr(I32_numtype, (i + 1)) $admininstr_val(val) CONST_admininstr(I32_numtype, (n - 1)) MEMORY.FILL_admininstr]) - -- otherwise + -- unless Step_read_before_memory.fill-succ: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, i) $admininstr_val(val) CONST_admininstr(I32_numtype, n) MEMORY.FILL_admininstr])) ;; 6-reduction.watsup:331.1-333.59 rule memory.copy-trap {i : nat, j : nat, n : n, z : state}: @@ -12070,19 +14223,19 @@ relation Step_read: `%~>%*`(config, admininstr*) ;; 6-reduction.watsup:335.1-338.14 rule memory.copy-zero {i : nat, j : nat, n : n, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr]), []) - -- otherwise + -- unless Step_read_before_memory.copy-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) -- if (n = 0) ;; 6-reduction.watsup:340.1-345.15 rule memory.copy-le {i : nat, j : nat, n : n, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr]), [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) LOAD_admininstr(I32_numtype, ?((8, U_sx)), 0, 0) STORE_admininstr(I32_numtype, ?(8), 0, 0) CONST_admininstr(I32_numtype, (j + 1)) CONST_admininstr(I32_numtype, (i + 1)) CONST_admininstr(I32_numtype, (n - 1)) MEMORY.COPY_admininstr]) - -- otherwise + -- unless Step_read_before_memory.copy-le: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) -- if (j <= i) ;; 6-reduction.watsup:347.1-351.15 rule memory.copy-gt {i : nat, j : nat, n : n, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr]), [CONST_admininstr(I32_numtype, ((j + n) - 1)) CONST_admininstr(I32_numtype, ((i + n) - 1)) LOAD_admininstr(I32_numtype, ?((8, U_sx)), 0, 0) STORE_admininstr(I32_numtype, ?(8), 0, 0) CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, (n - 1)) MEMORY.COPY_admininstr]) - -- otherwise + -- unless Step_read_before_memory.copy-gt: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.COPY_admininstr])) ;; 6-reduction.watsup:354.1-356.60 rule memory.init-trap {i : nat, j : nat, n : n, x : idx, z : state}: @@ -12092,14 +14245,14 @@ relation Step_read: `%~>%*`(config, admininstr*) ;; 6-reduction.watsup:358.1-361.14 rule memory.init-zero {i : nat, j : nat, n : n, x : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)]), []) - -- otherwise + -- unless Step_read_before_memory.init-zero: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) -- if (n = 0) ;; 6-reduction.watsup:363.1-367.15 rule memory.init-succ {i : nat, j : nat, n : n, x : idx, z : state}: `%~>%*`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)]), [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, $data(z, x)[i]) STORE_admininstr(I32_numtype, ?(8), 0, 0) CONST_admininstr(I32_numtype, (j + 1)) CONST_admininstr(I32_numtype, (i + 1)) CONST_admininstr(I32_numtype, (n - 1)) MEMORY.INIT_admininstr(x)]) - -- otherwise -- if (i < |$data(z, x)|) + -- unless Step_read_before_memory.init-succ: `%`(`%;%*`(z, [CONST_admininstr(I32_numtype, j) CONST_admininstr(I32_numtype, i) CONST_admininstr(I32_numtype, n) MEMORY.INIT_admininstr(x)])) ;; 6-reduction.watsup:3.1-3.63 relation Step: `%~>%`(config, config)