@ -76,6 +76,37 @@ module Make(Ord: OrderedType) =
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    (*  Sets are represented by balanced binary trees  ( the heights of the 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       children  differ  by  at  most  2  * ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    type  enumeration  =  End  |  More  of  elt  *  t  *  enumeration 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  rec  cons_enum  s  e  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      match  s  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        Empty  ->  e 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  Node { l ;  v ;  r }  ->  cons_enum  l  ( More ( v ,  r ,  e ) ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  rec  compare_aux  e1  e2  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        match  ( e1 ,  e2 )  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        ( End ,  End )  ->  0 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  ( End ,  _ )   ->  - 1 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  ( _ ,  End )  ->  1 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  ( More ( v1 ,  r1 ,  e1 ) ,  More ( v2 ,  r2 ,  e2 ) )  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          let  c  =  Ord . compare  v1  v2  in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  c  < >  0 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          then  c 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          else  compare_aux  ( cons_enum  r1  e1 )  ( cons_enum  r2  e2 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  compare  s1  s2  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      compare_aux  ( cons_enum  s1  End )  ( cons_enum  s2  End ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  equal  s1  s2  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      compare  s1  s2  =  0 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  rec  elements_aux  accu  =  function 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        Empty  ->  accu 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  Node { l ;  v ;  r }  ->  elements_aux  ( v  ::  elements_aux  accu  r )  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  elements  s  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      elements_aux  []  s 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  height  =  function 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        Empty  ->  0 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  Node  { h }  ->  h 
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -90,6 +121,27 @@ module Make(Ord: OrderedType) =
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      let  hr  =  match  r  with  Empty  ->  0  |  Node  { h }  ->  h  in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      Node { l ;  v ;  r ;  h = ( if  hl  > =  hr  then  hl  +  1  else  hr  +  1 ) } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  of_sorted_list  l  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      let  rec  sub  n  l  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        match  n ,  l  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  0 ,  l  ->  Empty ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  1 ,  x0  ::  l  ->  Node  { l = Empty ;  v = x0 ;  r = Empty ;  h = 1 } ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  2 ,  x0  ::  x1  ::  l  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            Node { l = Node { l = Empty ;  v = x0 ;  r = Empty ;  h = 1 } ;  v = x1 ;  r = Empty ;  h = 2 } ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  3 ,  x0  ::  x1  ::  x2  ::  l  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            Node { l = Node { l = Empty ;  v = x0 ;  r = Empty ;  h = 1 } ;  v = x1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                 r = Node { l = Empty ;  v = x2 ;  r = Empty ;  h = 1 } ;  h = 2 } ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  n ,  l  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          let  nl  =  n  /  2  in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          let  left ,  l  =  sub  nl  l  in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          match  l  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          |  []  ->  assert  false 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          |  mid  ::  l  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            let  right ,  l  =  sub  ( n  -  nl  -  1 )  l  in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            create  left  mid  right ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      fst  ( sub  ( List . length  l )  l ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    (*  Same as create, but performs one step of rebalancing if necessary. 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       Assumes  l  and  r  balanced  and  |  height  l  -  height  r  |  < =  3 . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       Inline  expansion  of  create  for  better  speed  in  the  most  frequent  case 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -333,30 +385,6 @@ module Make(Ord: OrderedType) =
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          |  ( l2 ,  true ,  r2 )  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              concat  ( diff  l1  l2 )  ( diff  r1  r2 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    type  enumeration  =  End  |  More  of  elt  *  t  *  enumeration 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  rec  cons_enum  s  e  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      match  s  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        Empty  ->  e 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  Node { l ;  v ;  r }  ->  cons_enum  l  ( More ( v ,  r ,  e ) ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  rec  compare_aux  e1  e2  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        match  ( e1 ,  e2 )  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        ( End ,  End )  ->  0 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  ( End ,  _ )   ->  - 1 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  ( _ ,  End )  ->  1 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  ( More ( v1 ,  r1 ,  e1 ) ,  More ( v2 ,  r2 ,  e2 ) )  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          let  c  =  Ord . compare  v1  v2  in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  c  < >  0 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          then  c 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          else  compare_aux  ( cons_enum  r1  e1 )  ( cons_enum  r2  e2 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  compare  s1  s2  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      compare_aux  ( cons_enum  s1  End )  ( cons_enum  s2  End ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  equal  s1  s2  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      compare  s1  s2  =  0 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  rec  subset  s1  s2  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      match  ( s1 ,  s2 )  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        Empty ,  _  -> 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -415,13 +443,6 @@ module Make(Ord: OrderedType) =
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        Empty  ->  0 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  Node { l ;  r }  ->  cardinal  l  +  1  +  cardinal  r 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  rec  elements_aux  accu  =  function 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        Empty  ->  accu 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  Node { l ;  v ;  r }  ->  elements_aux  ( v  ::  elements_aux  accu  r )  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  elements  s  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      elements_aux  []  s 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  choose  =  min_elt 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  choose_opt  =  min_elt_opt 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -552,27 +573,6 @@ module Make(Ord: OrderedType) =
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              try_concat  l'  r' 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         end 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  of_sorted_list  l  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      let  rec  sub  n  l  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        match  n ,  l  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  0 ,  l  ->  Empty ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  1 ,  x0  ::  l  ->  Node  { l = Empty ;  v = x0 ;  r = Empty ;  h = 1 } ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  2 ,  x0  ::  x1  ::  l  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            Node { l = Node { l = Empty ;  v = x0 ;  r = Empty ;  h = 1 } ;  v = x1 ;  r = Empty ;  h = 2 } ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  3 ,  x0  ::  x1  ::  x2  ::  l  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            Node { l = Node { l = Empty ;  v = x0 ;  r = Empty ;  h = 1 } ;  v = x1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                 r = Node { l = Empty ;  v = x2 ;  r = Empty ;  h = 1 } ;  h = 2 } ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        |  n ,  l  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          let  nl  =  n  /  2  in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          let  left ,  l  =  sub  nl  l  in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          match  l  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          |  []  ->  assert  false 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          |  mid  ::  l  -> 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            let  right ,  l  =  sub  ( n  -  nl  -  1 )  l  in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            create  left  mid  right ,  l 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      in 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      fst  ( sub  ( List . length  l )  l ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    let  of_list  l  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      match  l  with 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      |  []  ->  empty