caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Alain Frisch <frisch@clipper.ens.fr>
To: John Max Skaller <skaller@ozemail.com.au>
Cc: Caml list <caml-list@inria.fr>
Subject: Re: [Caml-list] equi-recursive Fold isomorphism
Date: Sun, 28 Jul 2002 22:14:59 +0200 (MET DST)	[thread overview]
Message-ID: <Pine.SOL.4.44.0207282143060.10604-100000@clipper.ens.fr> (raw)
In-Reply-To: <3D434CC3.6030508@ozemail.com.au>

On Sun, 28 Jul 2002, John Max Skaller wrote:

> Hmmm: Ocaml 3.04+15 with -rectypes
>
>
> # let rec x = (1,(1,(1,x)));;
> val x : int * (int * (int * 'a)) as 'a =
>  ....
>
> Seem like Ocaml doesn't minimise the type, but:
>
>
> let rec y = (1,y);;
>
> x = y;;
>
> Works correctly (so it knows the two types are comparable).
> Interestingly, the answer is false

Are you sure ?  It seems that the comparison doesn't terminate,
as expected (as it does not consume memory). The manual
says:
<<
Equality between cyclic data structures may not terminate.
>>


: both data structures
> consist of an infinite stream of 1's, represented by
> cycles of distinct lengths. No item by item comparison
> could reveal any distinction: the infinite tree expansions
> of the data structures are the same. Is Ocaml's answer correct?

As you know, to implement the comparison between cyclic values with the
expected behaviour, one has to use a coinductive algorithm with some kind
of memoization. This would be much slower for the non-cyclic case, and
many people expect a fast generic compare function. I would like to say
that you can always take the code in byterun/compare.c and implement your
own equirecursive generic comparison in C, but this is actually not
possible (you need the Is_young and Is_in_heap macros that are not
available). Using the mentioned Recurse module, you could do:

module I = struct
  type 'a t = Int of int | Pair of 'a * 'a

  let map f = function
    | Int i -> Int i
    | Pair (a,b) -> Pair (f a, f b)

  let equal f x y =
    match (x,y) with
      | (Int i, Int j) when i = j -> ()
      | (Pair (a1,b1), Pair (a2,b2)) -> f a1 a2; f b1 b2
      | _ -> raise Recursive.NotEqual

  let iter f x = ignore (map f x)
  let hash f x = Hashtbl.hash (map f x)
  let deep = 4
end

module X = Recursive.Make(I)


let cons x = let n = X.make () in X.define n x; n
let recurs f = let n = X.make () in X.define n (f n); n
let int' i = I.Int i
let int i = cons (int' i)
let pair' a b = I.Pair (a,b)
let pair a b = cons (pair' a b)

let x = recurs (fun x -> pair' (int 1) (pair (int 1) (pair (int 1) x)))
let y = recurs (fun y -> pair' (int 1) y)

let x = X.internalize x and y = X.internalize y
let () = Printf.printf "%i;%i;%b\n" (X.id x) (X.id y) (x = y)


(the equility test is specified by Recurse to run in constant time)


Side-note: be careful if you implement a language with subtyping and both
recursive types and recursive (cyclic) values. Indeed, the usual
equi-recursive definition of subtyping is not sound if you allow cyclic
values. For instance, the algorithm would say that the type ('a * 'a) as
'a is empty, even though it is inhabited by values.


-- Alain

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


  reply	other threads:[~2002-07-28 20:15 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-27 17:32 John Max Skaller
2002-07-27 19:43 ` Alain Frisch
2002-07-28  1:45   ` John Max Skaller
2002-07-28 20:14     ` Alain Frisch [this message]
2002-08-01 14:49   ` [Caml-list] Question about distribution John Max Skaller
2002-08-01 15:48     ` Xavier Leroy
2002-08-03 17:34     ` Daniel de Rauglaudre

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.SOL.4.44.0207282143060.10604-100000@clipper.ens.fr \
    --to=frisch@clipper.ens.fr \
    --cc=caml-list@inria.fr \
    --cc=skaller@ozemail.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).