Files
sdk/pkg/kernel/coq/ObjectModel.v
T
Samir Jindel 474c075794 [kernel] Simplified Coq AST and first draft of it's type system.
Details to come in discussions.

Bug:
Change-Id: Ia50d85dd27cde83e25086f64dc6746cc52036128
Reviewed-on: https://dart-review.googlesource.com/4941
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
2017-09-12 16:23:16 +00:00

142 lines
5.0 KiB
V

(* Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
* for details. All rights reserved. Use of this source code is governed by a
* BSD-style license that can be found in the LICENSE file. *)
Require Import Common.
Require Import Syntax.
Import Common.OptionMonad.
Module L := Common.ListExtensions.
Require Import Coq.Strings.String.
Fixpoint type_equiv (s : dart_type) (t : dart_type) : bool :=
match (s, t) with
| (DT_Interface_Type (Interface_Type s_class),
DT_Interface_Type (Interface_Type t_class)) =>
Nat.eqb s_class t_class
| (DT_Function_Type (Function_Type s_param s_ret),
DT_Function_Type (Function_Type t_param t_ret)) =>
type_equiv s_param t_param && type_equiv s_ret t_ret
| _ => false
end.
Notation "s t" := (type_equiv s t = true) (at level 70, no associativity).
Lemma type_equiv_trans : forall s t r, s t /\ t r -> s r.
Admitted.
(* Semantic Types *)
Record procedure_desc : Type := mk_procedure_desc {
pr_name : string;
pr_ref : nat;
pr_type : function_type;
}.
Definition procedure_dissect (p : procedure) : procedure_desc :=
let (memb, _, fn) := p in
let (nn, _, name) := memb in
let (name_str) := name in
let (ref) := nn in
let (id) := ref in
let (param, ret_type, _) := fn in
let (_, param_type, _) := param in
mk_procedure_desc name_str id (Function_Type param_type ret_type).
Record interface : Type := mk_interface {
procedures : list procedure_desc;
}.
(** Type envronment maps class IDs to their interface type. *)
Definition class_env : Type := NatMap.t interface.
Definition type_env : Type := NatMap.t dart_type.
Fixpoint class_type (CE : class_env) (c : class) : option class_env :=
let (nn_data, _, procedures) := c in
let (ref) := nn_data in
let (class_id) := ref in
let class_interface := mk_interface (map procedure_dissect procedures) in
let CE' := NatMap.add class_id class_interface CE in
if forallb (procedure_type CE') procedures then Some CE' else None
with procedure_type (CE : class_env) (p : procedure) : bool :=
let (_, _, fn) := p in
let (param, ret_type, body) := fn in
let (param_var, param_type, _) := param in
let TE := NatMap.add param_var param_type (NatMap.empty _) in
match statement_type CE TE body with
| Some (_, Some t) => type_equiv t ret_type
| _ => false
end
with statement_type (CE : class_env) (TE : type_env) (s : statement) :
option (type_env * option dart_type) :=
match s with
| S_Expression_Statement (Expression_Statement e) =>
_ <- expression_type CE TE e; [(TE, None)]
| S_Return_Statement (Return_Statement re) =>
rt <- expression_type CE TE re; [(TE, Some rt)]
| S_Variable_Declaration (Variable_Declaration _ _ None) => None
| S_Variable_Declaration (Variable_Declaration var type (Some init)) =>
init_type <- expression_type CE TE init;
if type_equiv init_type type then
[(NatMap.add var type TE, None)]
else
None
| S_Block (Block stmts) =>
let process_statements := fix process_statements TE stmts :=
match stmts with
| nil => [(TE, None)]
| (s::ss) =>
st <- statement_type CE TE s;
let (TE', s_rt) := st in
sst <- process_statements TE' ss;
let (TE'', ss_rt) := sst in
match (s_rt, ss_rt) with
| (None, ss_rt) => [(TE'', ss_rt)]
| (Some rt, None) => [(TE'', Some rt)]
| (Some rt, Some rt') =>
if type_equiv rt rt' then [(TE'', Some rt)] else None
end
end in
process_statements TE stmts
end
with expression_type (CE : class_env) (TE : type_env) (e : expression) : option dart_type :=
match e with
| E_Variable_Get (Variable_Get v) => NatMap.find v TE
| E_Property_Get (Property_Get rec prop) =>
rec_type <- expression_type CE TE rec;
let (prop_name) := prop in
match rec_type with
| DT_Function_Type _ => None
| DT_Interface_Type (Interface_Type class) =>
interface <- NatMap.find class CE;
proc_desc <- List.find (fun P =>
if string_dec (pr_name P) prop_name then true else false)
(procedures interface);
[DT_Function_Type (pr_type proc_desc)]
end
| E_Invocation_Expression (IE_Constructor_Invocation (Constructor_Invocation class _)) =>
_ <- NatMap.find class CE;
[DT_Interface_Type (Interface_Type class)]
| E_Invocation_Expression (IE_Method_Invocation (Method_Invocation rec method args _)) =>
rec_type <- expression_type CE TE rec;
let (method_name) := method in
match rec_type with
| DT_Function_Type fn_type =>
if string_dec "call" method_name then [rec_type] else None
| DT_Interface_Type (Interface_Type class) =>
interface <- NatMap.find class CE;
proc_desc <- List.find (fun P =>
if string_dec (pr_name P) method_name then true else false)
(procedures interface);
[DT_Function_Type (pr_type proc_desc)]
end
end
.
Lemma type_equiv_sanity1 :
forall CE TE e v s t et,
expression_type CE (NatMap.add v s TE) e = Some et /\ s t ->
exists es, expression_type CE (NatMap.add v t TE) e = Some es /\ et es.
Admitted.