Skip to content

Commit

Permalink
Fix totality checker in match_inp to correctly account for inductive …
Browse files Browse the repository at this point in the history
…type parameters (QuickChick#381)
  • Loading branch information
lemonidas authored Jun 21, 2024
1 parent f39a67b commit fc67c2d
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 2 deletions.
67 changes: 67 additions & 0 deletions examples/other/DependentTest.v
Original file line number Diff line number Diff line change
Expand Up @@ -432,5 +432,72 @@ Inductive goodFun : Foo -> Prop :=

Derive ArbitrarySizedSuchThat for (fun a => goodFun a).

Inductive Foo_and : (bool * bool) -> bool -> Prop :=
| Foo_andtt : Foo_and (true, true) true.

Inductive Foo_rel : nat -> bool -> Prop :=
| R1 : forall n,
Foo_rel n true
| R2' : forall a1 l1 a2 l2 l,
Foo_and (l1, l2) l ->
Foo_rel a1 l1 ->
Foo_rel a2 l2 ->
Foo_rel a1 l.

Derive Generator for (fun l12 => Foo_and l12 l).
Derive Generator for (fun a => Foo_rel a b).

Definition gen_foo_and (l : bool) : nat -> G (option (bool * bool)) :=
let
fix aux_arb (init_size size : nat) (l_0 : bool) {struct size} : G (option (bool * bool)) :=
match size with
| 0 | _ =>
backtrack
[(1,
thunkGen
(fun _ : unit => if l_0 then returnGen (Some (true, true)) else returnGen None))]
end in
fun size : nat => aux_arb size size l.

Lemma gen_foo_and_equality l :
gen_foo_and l = @arbitrarySizeST _ (fun l12 => Foo_and l12 l) _.
Proof. reflexivity. Qed.

Definition gen_foo_rel (b_ : bool) : nat -> G (option nat) :=
let
fix aux_arb (init_size size : nat) (b_0 : bool) {struct size} : G (option nat) :=
match size with
| 0 =>
backtrack
[(1,
thunkGen
(fun _ : unit =>
if b_0
then bindGen arbitrary (fun n : nat => returnGen (Some n))
else returnGen None)); (1, thunkGen (fun _ : unit => returnGen None))]
| S size' =>
backtrack
[(1,
thunkGen
(fun _ : unit =>
if b_0
then bindGen arbitrary (fun n : nat => returnGen (Some n))
else returnGen None));
(S size',
thunkGen
(fun _ : unit =>
bindOpt (genST (fun unkn_11_ : bool * bool => Foo_and unkn_11_ b_0))
(fun unkn_11_ : bool * bool =>
let (l1, l2) := unkn_11_ in
bindOpt (aux_arb init_size size' l1)
(fun a_ : nat =>
bindOpt (aux_arb init_size size' l2) (fun _ : nat => returnGen (Some a_))))))]
end in
fun size : nat => aux_arb size size b_.

Lemma gen_foo_rel_equality b :
gen_foo_rel b = @arbitrarySizeST _ (fun l => Foo_rel l b) _.
Proof. reflexivity. Qed.

Definition success := "success".
Print success.
6 changes: 4 additions & 2 deletions plugin/arbitrarySizedST.ml
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ let check_expr (n : int) (scrut : coq_expr) (left : coq_expr) (right : coq_expr)
]

let match_inp (inp : var) (pat : matcher_pat) (left : coq_expr) (right : coq_expr) =
msg_debug (str (Printf.sprintf "Calling match inp with %s %s\n" (var_to_string inp) (matcher_pat_to_string pat)) ++ fnl ());
let ret v left right =
construct_match (gVar v) ~catch_all:(Some right) [(pat, left)]
in
let catch_case =
match pat with
| MatchCtr (c, ls) ->
| MatchCtr (c, ls) ->
msg_debug (str (Printf.sprintf "In catch case: %s : %s\n" (matcher_pat_to_string pat) (string_of_int (num_of_ctrs c))) ++ fnl ());
(* Leo: This is a hack totality check for unary matches *)
if num_of_ctrs c = 1 && List.for_all (fun x -> match x with MatchU _ -> true | MatchCtr _ -> false) ls
if num_of_ctrs c = 1 && List.for_all (fun x -> match x with MatchU _ -> true | MatchParameter _ -> true | MatchCtr (c',_) -> belongs_to_inductive c') ls
then None
else Some right
| _ -> failwith "Toplevel match not a constructor?"
Expand Down
5 changes: 5 additions & 0 deletions plugin/genericLib.ml.cppo
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ let num_of_ctrs (c : constructor) =
let mib = Environ.lookup_mind mind env in
Array.length (mib.mind_packets.(n).mind_consnames)

let belongs_to_inductive (c : constructor) =
(* let env = Global.env () in *)
let glob_ref = Nametab.global c in
Globnames.isIndRef glob_ref

module type Ord_ty_ctr_type = sig
type t = ty_ctr
val compare : t -> t -> int
Expand Down
1 change: 1 addition & 0 deletions plugin/genericLib.mli
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ module type Ord_ctr_type = sig
module Ord_ctr : Ord_ctr_type

val num_of_ctrs : constructor -> int
val belongs_to_inductive : constructor -> bool

type ctr_rep = constructor * coq_type
val ctr_rep_to_string : ctr_rep -> string
Expand Down

0 comments on commit fc67c2d

Please sign in to comment.