Minuska.builtin.list_model
From Minuska Require Import
prelude
spec
model_functor
list_signature
model_algebra
(* model_functor *)
.
Definition list_function_interp
(InnerT : Type)
(TermSymbol : Type)
(NondetValue : Type)
(Carrier : Type)
(_WB : Injection bool Carrier)
(_WI : Injection InnerT Carrier)
(_WL : Injection (list InnerT) Carrier)
(asi : Carrier -> option (InnerT))
(asl : Carrier -> option (list InnerT))
:
ListFunSymbol ->
NondetValue ->
list (@TermOver' TermSymbol Carrier) ->
option (@TermOver' TermSymbol Carrier)
:=
fun f nd args =>
match f with
| list_nil =>
match args with
| [] => Some (t_over (inject (list InnerT) Carrier []))
| _ => None
end
| list_cons =>
match args with
| (t_over x1)::(t_over x2)::[] =>
match (asi x1), (asl x2) with
| Some v, Some l => Some (t_over (inject (list InnerT) Carrier (v::l)))
| _, _ => None
end
| _ => None
end
| list_head =>
match args with
| (t_over x1)::[] =>
match asl x1 with
| Some [] => None
| Some (h::_) => Some (t_over (inject InnerT Carrier h))
| _ => None
end
| _ => None
end
| list_tail =>
match args with
| (t_over x1)::[] =>
match asl x1 with
| Some [] => None
| Some (_::t) => Some (t_over (inject (list InnerT) Carrier t))
| _ => None
end
| _ => None
end
| list_is_nil =>
match args with
| (t_over x1)::[] =>
match (asl x1) with
| Some l => Some (t_over (inject bool Carrier (bool_decide (l = []))))
| _ => None
end
| _ => None
end
end
.
Definition list_predicate_interp
(InnerT : Type)
(TermSymbol : Type)
(NondetValue : Type)
(Carrier : Type)
(_WB : Injection bool Carrier)
(_WI : Injection InnerT Carrier)
(_WL : Injection (list InnerT) Carrier)
(asi : Carrier -> option (InnerT))
(asl : Carrier -> option (list InnerT))
:
ListPredSymbol ->
NondetValue ->
list (@TermOver' TermSymbol Carrier) ->
option bool
:=
fun p nd args =>
match p with
| list_is =>
match args with
| (t_over x1)::[] =>
match (asl x1) with
| Some _ => Some true
| _ => Some false
end
| _ => None
end
end
.
Variant simple_list_carrier (Inner : Type) :=
| slc_inner (x : Inner)
| slc_list (l : list Inner)
.
#[local]
Instance simple_list_carrier__eqdec
(Inner : Type)
{_ : EqDecision Inner}
: EqDecision (simple_list_carrier Inner)
.
Proof.
ltac1:(solve_decision).
Defined.
#[local]
Program Instance simple_list_carrier__countable
(Inner : Type)
{_ : EqDecision Inner}
{_ : Countable Inner}
: Countable (simple_list_carrier Inner) := {|
encode := fun slc =>
stdpp.countable.encode (
match slc with
| slc_inner _ x => inl x
| slc_list _ l => inr l
end
)
;
decode := fun (p : positive) =>
match (@stdpp.countable.decode (Inner+(list Inner)) _ _ p) with
| Some (inl x) => Some (slc_inner _ x)
| Some (inr l) => Some (slc_list _ l)
| None => None
end
|}.
Next Obligation.
rewrite decode_encode.
ltac1:(repeat case_match; simplify_eq/=);
reflexivity.
Qed.
Fail Next Obligation.
(*
TODO: So far, the output algebra has only predicates and functions of list.
We need to find a way to add there the original Fs and Ps back.
*)
Program Definition list_wrapper
(Vdeps Vours : Type)
(NV Sy Fs Ps : Type)
(M : RelaxedValueAlgebra Vdeps Vours NV Sy Fs Ps)
:
RelaxedValueAlgebra bool (simple_list_carrier Vours) NV Sy ListFunSymbol ListPredSymbol
:= {|
rva_over :=
fun
(Carrier : Type)
(inja : Injection (bool) Carrier)
(injb : ReversibleInjection
(simple_list_carrier Vours)
Carrier
)
=>
let asi := (fun c =>
match (@ri_reverse _ _ injb) c with Some d => (
match d with
| slc_inner _ d' => Some d'
| _ => None
end
)
| None => None end
) in
let asl := (fun c =>
match (@ri_reverse _ _ injb) c with Some d => (
match d with
| slc_list _ d' => Some d'
| _ => None
end
)
| None => None end
) in
let WL : Injection (list (Vours)) Carrier := {|
inject := fun l => @inject _ _ (@ri_injection _ _ injb) (slc_list _ l)
|} in
let WI := {|
inject := fun i => @inject _ _ (@ri_injection _ _ injb) (slc_inner _ i)
|} in
let WB := {|
inject := fun b => @inject _ _ inja (b)
|} in
{|
builtin_function_interp := fun (f : list_signature.ListFunSymbol) => list_function_interp Vours Sy NV Carrier WB WI WL asi asl f;
builtin_predicate_interp := fun (p :list_signature.ListPredSymbol) => list_predicate_interp Vours Sy NV Carrier WB WI WL asi asl p;
|}
|}
.
Next Obligation.
apply inject_inj in H.
ltac1:(injection H as H).
exact H.
Qed.
Next Obligation.
apply inject_inj in H.
ltac1:(injection H as H).
exact H.
Qed.
Next Obligation.
apply (inj (inject bool Carrier)) in H.
exact H.
Qed.
Fail Next Obligation.
About list_wrapper.
prelude
spec
model_functor
list_signature
model_algebra
(* model_functor *)
.
Definition list_function_interp
(InnerT : Type)
(TermSymbol : Type)
(NondetValue : Type)
(Carrier : Type)
(_WB : Injection bool Carrier)
(_WI : Injection InnerT Carrier)
(_WL : Injection (list InnerT) Carrier)
(asi : Carrier -> option (InnerT))
(asl : Carrier -> option (list InnerT))
:
ListFunSymbol ->
NondetValue ->
list (@TermOver' TermSymbol Carrier) ->
option (@TermOver' TermSymbol Carrier)
:=
fun f nd args =>
match f with
| list_nil =>
match args with
| [] => Some (t_over (inject (list InnerT) Carrier []))
| _ => None
end
| list_cons =>
match args with
| (t_over x1)::(t_over x2)::[] =>
match (asi x1), (asl x2) with
| Some v, Some l => Some (t_over (inject (list InnerT) Carrier (v::l)))
| _, _ => None
end
| _ => None
end
| list_head =>
match args with
| (t_over x1)::[] =>
match asl x1 with
| Some [] => None
| Some (h::_) => Some (t_over (inject InnerT Carrier h))
| _ => None
end
| _ => None
end
| list_tail =>
match args with
| (t_over x1)::[] =>
match asl x1 with
| Some [] => None
| Some (_::t) => Some (t_over (inject (list InnerT) Carrier t))
| _ => None
end
| _ => None
end
| list_is_nil =>
match args with
| (t_over x1)::[] =>
match (asl x1) with
| Some l => Some (t_over (inject bool Carrier (bool_decide (l = []))))
| _ => None
end
| _ => None
end
end
.
Definition list_predicate_interp
(InnerT : Type)
(TermSymbol : Type)
(NondetValue : Type)
(Carrier : Type)
(_WB : Injection bool Carrier)
(_WI : Injection InnerT Carrier)
(_WL : Injection (list InnerT) Carrier)
(asi : Carrier -> option (InnerT))
(asl : Carrier -> option (list InnerT))
:
ListPredSymbol ->
NondetValue ->
list (@TermOver' TermSymbol Carrier) ->
option bool
:=
fun p nd args =>
match p with
| list_is =>
match args with
| (t_over x1)::[] =>
match (asl x1) with
| Some _ => Some true
| _ => Some false
end
| _ => None
end
end
.
Variant simple_list_carrier (Inner : Type) :=
| slc_inner (x : Inner)
| slc_list (l : list Inner)
.
#[local]
Instance simple_list_carrier__eqdec
(Inner : Type)
{_ : EqDecision Inner}
: EqDecision (simple_list_carrier Inner)
.
Proof.
ltac1:(solve_decision).
Defined.
#[local]
Program Instance simple_list_carrier__countable
(Inner : Type)
{_ : EqDecision Inner}
{_ : Countable Inner}
: Countable (simple_list_carrier Inner) := {|
encode := fun slc =>
stdpp.countable.encode (
match slc with
| slc_inner _ x => inl x
| slc_list _ l => inr l
end
)
;
decode := fun (p : positive) =>
match (@stdpp.countable.decode (Inner+(list Inner)) _ _ p) with
| Some (inl x) => Some (slc_inner _ x)
| Some (inr l) => Some (slc_list _ l)
| None => None
end
|}.
Next Obligation.
rewrite decode_encode.
ltac1:(repeat case_match; simplify_eq/=);
reflexivity.
Qed.
Fail Next Obligation.
(*
TODO: So far, the output algebra has only predicates and functions of list.
We need to find a way to add there the original Fs and Ps back.
*)
Program Definition list_wrapper
(Vdeps Vours : Type)
(NV Sy Fs Ps : Type)
(M : RelaxedValueAlgebra Vdeps Vours NV Sy Fs Ps)
:
RelaxedValueAlgebra bool (simple_list_carrier Vours) NV Sy ListFunSymbol ListPredSymbol
:= {|
rva_over :=
fun
(Carrier : Type)
(inja : Injection (bool) Carrier)
(injb : ReversibleInjection
(simple_list_carrier Vours)
Carrier
)
=>
let asi := (fun c =>
match (@ri_reverse _ _ injb) c with Some d => (
match d with
| slc_inner _ d' => Some d'
| _ => None
end
)
| None => None end
) in
let asl := (fun c =>
match (@ri_reverse _ _ injb) c with Some d => (
match d with
| slc_list _ d' => Some d'
| _ => None
end
)
| None => None end
) in
let WL : Injection (list (Vours)) Carrier := {|
inject := fun l => @inject _ _ (@ri_injection _ _ injb) (slc_list _ l)
|} in
let WI := {|
inject := fun i => @inject _ _ (@ri_injection _ _ injb) (slc_inner _ i)
|} in
let WB := {|
inject := fun b => @inject _ _ inja (b)
|} in
{|
builtin_function_interp := fun (f : list_signature.ListFunSymbol) => list_function_interp Vours Sy NV Carrier WB WI WL asi asl f;
builtin_predicate_interp := fun (p :list_signature.ListPredSymbol) => list_predicate_interp Vours Sy NV Carrier WB WI WL asi asl p;
|}
|}
.
Next Obligation.
apply inject_inj in H.
ltac1:(injection H as H).
exact H.
Qed.
Next Obligation.
apply inject_inj in H.
ltac1:(injection H as H).
exact H.
Qed.
Next Obligation.
apply (inj (inject bool Carrier)) in H.
exact H.
Qed.
Fail Next Obligation.
About list_wrapper.