Removing all clutter, this works (also paying the computational cost of the _ghost_ `f`) ``` let rec flatten_tree (t: tree 'a) : list 'a = match t with | Leaf v -> [v] | Branch subtrees -> let rec f: l:list (tree 'a){l << t} -> list (t': tree 'a{t' << t}) = function | [] -> [] | t' :: ts -> t' :: f ts in List.Tot.flatten (List.Tot.map flatten_tree (f subtrees)) ```
On Wed, Apr 12, 2017 at 12:57 PM, Catalin Hritcu <catalin.hri...@gmail.com> wrote: > >> I wonder if there's a different way to phrase this problem that would > >> grant us as much flexibility as Coq without the modularity cost. I > think > >> the comment in the snippet Nik pointed to earlier > >> (https://github.com/FStarLang/FStar/blob/master/examples/ter > mination/termination.fst#L118) > >> hints at something like this. > > Nik's trick directly works here, using the fact that `flatten_list` is > polymorphic: > ``` > let rec flatten_list (#a #b:Type) (l:(list b)) (f:(b -> list a)) : list a = > match l with > | [] -> [] > | hd::tl -> FStar.List.append (f hd) (flatten_list tl f) > > val list_subterm_ordering_lemma: > #a:eqtype > -> #b:Type > -> l:list a > -> bound:b > -> x:a > -> Lemma (requires (l << bound)) > (ensures (FStar.List.mem x l ==> x << > bound)) > [SMTPat (FStar.List.mem x l); > SMTPatT (x << bound)] > let rec list_subterm_ordering_lemma #a #b l bound x = match l with > | [] -> () > | hd::tl -> list_subterm_ordering_lemma tl bound x > > val move_refinement: #a:eqtype > -> #p:(a -> Type) > -> l:list a{forall z. FStar.List.mem z l ==> p z} > -> Tot (list (x:a{p x})) > let rec move_refinement #a #p l = match l with > | [] -> [] > | hd::tl -> hd::move_refinement #a #p tl > > let rec flatten_tree (#a:eqtype) (t:tree a) : list a = > match t with > | Leaf v -> [v] > | Branch l -> let l = move_refinement #_ #(fun aa -> aa << t) l in > flatten_list l flatten_tree > > ``` > > The problem I see with Nik's trick is that adding "ghost" in a comment: > ``` > let l = move_refinement #_ #(fun aa -> aa << v) l in (* ghost *) > ``` > doesn't make something Ghost in F*, and in fact move_refinement would > currently have a significant computational cost at the moment. > > Catalin >
_______________________________________________ fstar-club mailing list fstar-club@lists.gforge.inria.fr https://lists.gforge.inria.fr/mailman/listinfo/fstar-club