Index: mlc/fcmp.hh
===================================================================
--- mlc/fcmp.hh	(revision 268)
+++ mlc/fcmp.hh	(working copy)
@@ -29,10 +29,13 @@
 # define METALIC_FCMP_HH
 
 # include <mlc/afun.hh>
+# include <mlc/ftraits.hh>
 
+# include <algorithm>
 
 
-# define mlc_decl_mfun_cmp(OperatorName, OperatorSymbol)					\
+
+# define mlc_decl_fun_cmp(OperatorName, OperatorBody)						\
 												\
   namespace fun											\
   {												\
@@ -48,19 +51,21 @@
   template <typename T1, typename T2>								\
   struct set_props < category::fun, fun::OperatorName##_<T1,T2> >				\
   {												\
-    typedef bool res_type;									\
+    typedef typename traits_##OperatorName<T1,T2>::ret res_type;				\
     typedef T1 arg1_type;									\
     typedef T2 arg2_type;									\
   };												\
 												\
   namespace fun											\
   {												\
-    template <typename T1, typename T2>								\
+    template <typename T1, typename T2 = T1>							\
     struct OperatorName##_ : public mlc::abstract::binary_function< OperatorName##_<T1,T2> >	\
     {												\
-      bool impl_binop(const T1& arg1, const T2& arg2) const					\
+      typedef OperatorName##_<T1,T2> self_type;							\
+      mlc_fun_type_of(self_type, res)								\
+      impl_binop(const T1& lhs, const T2& rhs) const						\
       {												\
-	return arg1 OperatorSymbol arg2;							\
+	return OperatorBody;									\
       }												\
     };												\
   }												\
@@ -75,17 +80,21 @@
 namespace mlc
 {
 
-  mlc_decl_mfun_cmp( eq,      == );
-  mlc_decl_mfun_cmp( neq,     != );
+  mlc_decl_fun_cmp( eq,      lhs == rhs );
+  mlc_decl_fun_cmp( neq,     lhs != rhs );
 
-  mlc_decl_mfun_cmp( less,    <  );
-  mlc_decl_mfun_cmp( leq,     <= );
+  mlc_decl_fun_cmp( less,    lhs <  rhs );
+  mlc_decl_fun_cmp( leq,     lhs <= rhs );
 
-  mlc_decl_mfun_cmp( greater, >  );
-  mlc_decl_mfun_cmp( geq,     >= );
+  mlc_decl_fun_cmp( greater, lhs >  rhs );
+  mlc_decl_fun_cmp( geq,     lhs >= rhs );
 
 } // end of namespace mlc
 
 
+// FIXME: min-like functions should be defined here
+// instead of in farith.hh...
 
+
+
 #endif // ! METALIC_FCMP_HH
Index: mlc/fun.hh
===================================================================
--- mlc/fun.hh	(revision 268)
+++ mlc/fun.hh	(working copy)
@@ -28,392 +28,394 @@
 #ifndef METALIC_FUN_HH
 # define METALIC_FUN_HH
 
-# include <mlc/any.hh>
+# include <mlc/afun.hh>
 
+// # include <mlc/any.hh>
 
-// fwd decls
-namespace std {
-  template <class Arg, class Ret> struct unary_function;
-  template <class Arg1, class Arg2, class Ret> struct binary_function;
-}
 
+// // fwd decls
+// namespace std {
+//   template <class Arg, class Ret> struct unary_function;
+//   template <class Arg1, class Arg2, class Ret> struct binary_function;
+// }
 
 
-namespace mlc
-{
 
-  // Fwd decl.
-  template <typename T>
-  struct function_traits;
+// namespace mlc
+// {
 
+//   // Fwd decl.
+//   template <typename T>
+//   struct function_traits;
 
-  /*---------------.
-  | Abstractions.  |
-  `---------------*/
 
-  namespace abstract {
+//   /*---------------.
+//   | Abstractions.  |
+//   `---------------*/
 
-    template <typename E>
-    class unary_function : public mlc::any<E>
-    {
-    public:
-      typedef E exact_type;
-      typedef typename function_traits<exact_type>::argument_type
-        argument_type;
-      typedef typename function_traits<exact_type>::result_type
-        result_type;
+//   namespace abstract {
 
-    public:
-      result_type
-      operator()(const argument_type& arg) const
-      {
-	// Check for "exact_type::impl_op_paren".
-	typedef
-	  result_type (exact_type::*fun_type)(const argument_type&) const;
-	static fun_type fun_adr = &exact_type::impl_op_paren;
-	assert(fun_adr != 0);
+//     template <typename E>
+//     class unary_function : public mlc::any<E>
+//     {
+//     public:
+//       typedef E exact_type;
+//       typedef typename function_traits<exact_type>::argument_type
+//         argument_type;
+//       typedef typename function_traits<exact_type>::result_type
+//         result_type;
 
-	return this->exact().impl_op_paren(arg);
-      }
-    };
+//     public:
+//       result_type
+//       operator()(const argument_type& arg) const
+//       {
+// 	// Check for "exact_type::impl_op_paren".
+// 	typedef
+// 	  result_type (exact_type::*fun_type)(const argument_type&) const;
+// 	static fun_type fun_adr = &exact_type::impl_op_paren;
+// 	assert(fun_adr != 0);
 
-    // FIXME: Add meta_unary_function.
+// 	return this->exact().impl_op_paren(arg);
+//       }
+//     };
 
-    template <typename E>
-    class binary_function : public mlc::any<E>
-    {
-    public:
-      typedef E exact_type;
-      typedef typename function_traits<exact_type>::argument1_type
-        argument1_type;
-      typedef typename function_traits<exact_type>::argument2_type
-        argument2_type;
-      typedef typename function_traits<exact_type>::result_type
-        result_type;
+//     // FIXME: Add meta_unary_function.
 
-    public:
-      result_type
-      operator()(const argument1_type& arg1, const argument2_type& arg2) const
-      {
-	// Check for "exact_type::impl_op_paren".
-	typedef
-	  result_type (exact_type::*fun_type)(const argument1_type&,
-					      const argument2_type&) const;
-	static fun_type fun_adr = &exact_type::impl_op_paren;
-	assert(fun_adr != 0);
+//     template <typename E>
+//     class binary_function : public mlc::any<E>
+//     {
+//     public:
+//       typedef E exact_type;
+//       typedef typename function_traits<exact_type>::argument1_type
+//         argument1_type;
+//       typedef typename function_traits<exact_type>::argument2_type
+//         argument2_type;
+//       typedef typename function_traits<exact_type>::result_type
+//         result_type;
 
-	return this->exact().impl_op_paren(arg1, arg2);
-      }
-    };
+//     public:
+//       result_type
+//       operator()(const argument1_type& arg1, const argument2_type& arg2) const
+//       {
+// 	// Check for "exact_type::impl_op_paren".
+// 	typedef
+// 	  result_type (exact_type::*fun_type)(const argument1_type&,
+// 					      const argument2_type&) const;
+// 	static fun_type fun_adr = &exact_type::impl_op_paren;
+// 	assert(fun_adr != 0);
+
+// 	return this->exact().impl_op_paren(arg1, arg2);
+//       }
+//     };
     
-    // FIXME: Add meta_binary_function.
+//     // FIXME: Add meta_binary_function.
 
-  } // end of namespace abstract
+//   } // end of namespace abstract
 
 
-  enum function_type
-    {
-      unknown_function_tag = 0,
-      // C-like functions.
-      classic_unary_function_tag,
-      classic_unary_function_ptr_tag,
-      classic_binary_function_tag,
-      classic_binary_function_ptr_tag,
-      // Functions deriving from the std namespace.
-      std_unary_function_tag,
-      std_binary_function_tag,
-      // Functions deriving from the oln namespace.
-      oln_unary_function_tag,
-      oln_binary_function_tag,
-      oln_meta_unary_function_tag
-    };
+//   enum function_type
+//     {
+//       unknown_function_tag = 0,
+//       // C-like functions.
+//       classic_unary_function_tag,
+//       classic_unary_function_ptr_tag,
+//       classic_binary_function_tag,
+//       classic_binary_function_ptr_tag,
+//       // Functions deriving from the std namespace.
+//       std_unary_function_tag,
+//       std_binary_function_tag,
+//       // Functions deriving from the oln namespace.
+//       oln_unary_function_tag,
+//       oln_binary_function_tag,
+//       oln_meta_unary_function_tag
+//     };
 
-  struct fun_info_helper
-  {
-    template <function_type t>
-    struct case_ { char dummy[t]; };
+//   struct fun_info_helper
+//   {
+//     template <function_type t>
+//     struct case_ { char dummy[t]; };
 
-    // C-like functions.
+//     // C-like functions.
 
-    template <typename A, typename R>
-    static case_<classic_unary_function_tag> on(R (**)(A));
+//     template <typename A, typename R>
+//     static case_<classic_unary_function_tag> on(R (**)(A));
 
-    template <typename A, typename R>
-    static case_<classic_unary_function_ptr_tag> on(R (*)(A));
+//     template <typename A, typename R>
+//     static case_<classic_unary_function_ptr_tag> on(R (*)(A));
 
-    template <typename A1, typename A2, typename R>
-    static case_<classic_binary_function_tag> on(R (**)(A1, A2));
+//     template <typename A1, typename A2, typename R>
+//     static case_<classic_binary_function_tag> on(R (**)(A1, A2));
 
-    template <typename A1, typename A2, typename R>
-    static case_<classic_binary_function_ptr_tag> on(R (*)(A1, A2));
+//     template <typename A1, typename A2, typename R>
+//     static case_<classic_binary_function_ptr_tag> on(R (*)(A1, A2));
 
-    // Functions deriving from the std namespace.
+//     // Functions deriving from the std namespace.
 
-    template <typename A, typename R>
-    static case_<std_unary_function_tag>
-    on(const std::unary_function<A, R>*);
+//     template <typename A, typename R>
+//     static case_<std_unary_function_tag>
+//     on(const std::unary_function<A, R>*);
 
-    template <typename A1, typename A2, typename R>
-    static case_<std_binary_function_tag>
-    on(const std::binary_function<A1, A2, R>*);
+//     template <typename A1, typename A2, typename R>
+//     static case_<std_binary_function_tag>
+//     on(const std::binary_function<A1, A2, R>*);
 
-    // Functions deriving from the oln namespace.
-    // FIXME: To do.
+//     // Functions deriving from the oln namespace.
+//     // FIXME: To do.
 
-    static case_<unknown_function_tag> on(...); 
-  };
+//     static case_<unknown_function_tag> on(...); 
+//   };
 
 
-  /*--------------------------------.
-  | Helpers for classic functions.  |
-  `--------------------------------*/
+//   /*--------------------------------.
+//   | Helpers for classic functions.  |
+//   `--------------------------------*/
 
-  template <typename A>
-  struct get_result;
+//   template <typename A>
+//   struct get_result;
 
-  template <typename A, typename R>
-  struct get_result <R (*)(A)> { typedef R ret; };
+//   template <typename A, typename R>
+//   struct get_result <R (*)(A)> { typedef R ret; };
 
-  template <typename A1, typename A2, typename R>
-  struct get_result <R (*)(A1,A2)> { typedef R ret; };
+//   template <typename A1, typename A2, typename R>
+//   struct get_result <R (*)(A1,A2)> { typedef R ret; };
 
 
-  template <typename A>
-  struct get_argument;
+//   template <typename A>
+//   struct get_argument;
 
-  template <typename A, typename R>
-  struct get_argument <R (*)(A)> { typedef A ret; };
+//   template <typename A, typename R>
+//   struct get_argument <R (*)(A)> { typedef A ret; };
 
 
-  template <typename A>
-  struct get_argument1;
+//   template <typename A>
+//   struct get_argument1;
 
-  template <typename A1, typename A2, typename R>
-  struct get_argument1 <R (*)(A1, A2)> { typedef A1 ret; };
+//   template <typename A1, typename A2, typename R>
+//   struct get_argument1 <R (*)(A1, A2)> { typedef A1 ret; };
 
 
-  template <typename A>
-  struct get_argument2;
+//   template <typename A>
+//   struct get_argument2;
 
-  template <typename A1, typename A2, typename R>
-  struct get_argument2 <R (*)(A1, A2)> { typedef A2 ret; };
+//   template <typename A1, typename A2, typename R>
+//   struct get_argument2 <R (*)(A1, A2)> { typedef A2 ret; };
 
 
-  /*-----------------------.
-  | Function information.  |
-  `-----------------------*/
+//   /*-----------------------.
+//   | Function information.  |
+//   `-----------------------*/
 
-  // Create a static pointer on type T.
-  template <typename T>
-  struct make
-  {
-    static T* ptr();
-  };
+//   // Create a static pointer on type T.
+//   template <typename T>
+//   struct make
+//   {
+//     static T* ptr();
+//   };
 
 
-  // Information on result type and argument type(s).
-  template <typename F, typename T, unsigned>
-  struct fun_info;
+//   // Information on result type and argument type(s).
+//   template <typename F, typename T, unsigned>
+//   struct fun_info;
 
-  // R (*)(A).
-  template <typename F, typename T>
-  struct fun_info <F, T, classic_unary_function_tag>
-  {
-    typedef typename get_argument<F>::ret argument_type;
-    typedef typename get_result<F>::ret result_type;
-  };
+//   // R (*)(A).
+//   template <typename F, typename T>
+//   struct fun_info <F, T, classic_unary_function_tag>
+//   {
+//     typedef typename get_argument<F>::ret argument_type;
+//     typedef typename get_result<F>::ret result_type;
+//   };
 
-  // R (**)(A).
-  template <typename F, typename T>
-  struct fun_info <F, T, classic_unary_function_ptr_tag>
-  {
-    typedef typename get_argument<F*>::ret argument_type;
-    typedef typename get_result<F*>::ret result_type;
-  };
+//   // R (**)(A).
+//   template <typename F, typename T>
+//   struct fun_info <F, T, classic_unary_function_ptr_tag>
+//   {
+//     typedef typename get_argument<F*>::ret argument_type;
+//     typedef typename get_result<F*>::ret result_type;
+//   };
 
-  // R (*)(A1, A2).
-  template <typename F, typename T>
-  struct fun_info <F, T, classic_binary_function_tag>
-  {
-    typedef typename get_argument1<F>::ret argument1_type;
-    typedef typename get_argument2<F>::ret argument2_type;
-    typedef typename get_result<F>::ret result_type;
-  };
+//   // R (*)(A1, A2).
+//   template <typename F, typename T>
+//   struct fun_info <F, T, classic_binary_function_tag>
+//   {
+//     typedef typename get_argument1<F>::ret argument1_type;
+//     typedef typename get_argument2<F>::ret argument2_type;
+//     typedef typename get_result<F>::ret result_type;
+//   };
 
-  // R (**)(A1, A2).
-  template <typename F, typename T>
-  struct fun_info <F, T, classic_binary_function_ptr_tag>
-  {
-    typedef typename get_argument1<F*>::ret argument1_type;
-    typedef typename get_argument2<F*>::ret argument2_type;
-    typedef typename get_result<F*>::ret result_type;
-  };
+//   // R (**)(A1, A2).
+//   template <typename F, typename T>
+//   struct fun_info <F, T, classic_binary_function_ptr_tag>
+//   {
+//     typedef typename get_argument1<F*>::ret argument1_type;
+//     typedef typename get_argument2<F*>::ret argument2_type;
+//     typedef typename get_result<F*>::ret result_type;
+//   };
 
-  // std::unary_function<A, R>
-  template <typename F, typename T>
-  struct fun_info <F, T, std_unary_function_tag>
-  {
-    typedef typename F::argument_type argument_type;
-    typedef typename F::result_type result_type;
-  };
+//   // std::unary_function<A, R>
+//   template <typename F, typename T>
+//   struct fun_info <F, T, std_unary_function_tag>
+//   {
+//     typedef typename F::argument_type argument_type;
+//     typedef typename F::result_type result_type;
+//   };
 
-  // std::binary_function<A1, A2, R>
-  template <typename F, typename T>
-  struct fun_info <F, T, std_binary_function_tag>
-  {
-    typedef typename F::first_argument_type argument1_type;
-    typedef typename F::second_argument_type argument2_type;
-    typedef typename F::result_type result_type;
-  };
+//   // std::binary_function<A1, A2, R>
+//   template <typename F, typename T>
+//   struct fun_info <F, T, std_binary_function_tag>
+//   {
+//     typedef typename F::first_argument_type argument1_type;
+//     typedef typename F::second_argument_type argument2_type;
+//     typedef typename F::result_type result_type;
+//   };
 
-  // FIXME: To be re-enabled later.
-# if 0
-  // oln::unary_function<E>
-  template <typename F, typename T>
-  struct fun_info <F, T, oln_unary_function_tag>
-  {
-    typedef oln_result_type(F) result_type;
-  };
+//   // FIXME: To be re-enabled later.
+// # if 0
+//   // oln::unary_function<E>
+//   template <typename F, typename T>
+//   struct fun_info <F, T, oln_unary_function_tag>
+//   {
+//     typedef oln_result_type(F) result_type;
+//   };
 
-  // oln::binary_function<E>
-  template <typename F, typename T>
-  struct fun_info <F, T, oln_binary_function_tag>
-  {
-    typedef oln_result_type(F) result_type;
-  };
+//   // oln::binary_function<E>
+//   template <typename F, typename T>
+//   struct fun_info <F, T, oln_binary_function_tag>
+//   {
+//     typedef oln_result_type(F) result_type;
+//   };
 
-  // oln::meta_unary_function<E>
-  template <typename F, typename T>
-  struct fun_info <F, T, oln_meta_unary_function_tag>
-  {
-    typedef oln_result_type_from(F,T) result_type;
-  };
-# endif
+//   // oln::meta_unary_function<E>
+//   template <typename F, typename T>
+//   struct fun_info <F, T, oln_meta_unary_function_tag>
+//   {
+//     typedef oln_result_type_from(F,T) result_type;
+//   };
+// # endif
 
 
-  /*-------------------------------------.
-  | Unary functions, with their traits.  |
-  `-------------------------------------*/
+//   /*-------------------------------------.
+//   | Unary functions, with their traits.  |
+//   `-------------------------------------*/
 
-  // Fwd decl.
-  template <typename F>
-  class unary_function;
+//   // Fwd decl.
+//   template <typename F>
+//   class unary_function;
 
-  template <typename F>
-  struct function_traits< unary_function <F> >
-  {
-    static const int case_id = sizeof(fun_info_helper::on(make<F>::ptr()));
-    typedef typename fun_info<F, void, case_id>::argument_type argument_type;
-    typedef typename fun_info<F, void, case_id>::result_type result_type;
-  };
+//   template <typename F>
+//   struct function_traits< unary_function <F> >
+//   {
+//     static const int case_id = sizeof(fun_info_helper::on(make<F>::ptr()));
+//     typedef typename fun_info<F, void, case_id>::argument_type argument_type;
+//     typedef typename fun_info<F, void, case_id>::result_type result_type;
+//   };
 
-  template <typename F>
-  class unary_function :
-    public mlc::abstract::unary_function< unary_function<F> >
-  {
-  public:
-    typedef unary_function<F> self_type;
-    typedef abstract::unary_function< unary_function<F> > super_type;
+//   template <typename F>
+//   class unary_function :
+//     public mlc::abstract::unary_function< unary_function<F> >
+//   {
+//   public:
+//     typedef unary_function<F> self_type;
+//     typedef abstract::unary_function< unary_function<F> > super_type;
 
-    typedef typename function_traits<self_type>::argument_type argument_type;
-    typedef typename function_traits<self_type>::result_type result_type;
+//     typedef typename function_traits<self_type>::argument_type argument_type;
+//     typedef typename function_traits<self_type>::result_type result_type;
 
-  public:
-    unary_function(F f) : super_type(), f_(f)
-    {
-    }
+//   public:
+//     unary_function(F f) : super_type(), f_(f)
+//     {
+//     }
 
-    result_type
-    impl_op_paren (const argument_type& arg) const
-    {
-      return f_(arg);
-    }
+//     result_type
+//     impl_op_paren (const argument_type& arg) const
+//     {
+//       return f_(arg);
+//     }
 
-  private:
-    F f_;
-  };
+//   private:
+//     F f_;
+//   };
 
-  template <typename F>
-  unary_function<F>
-  make_unary_fun(F f)
-  {
-    return unary_function<F> (f);
-  }
+//   template <typename F>
+//   unary_function<F>
+//   make_unary_fun(F f)
+//   {
+//     return unary_function<F> (f);
+//   }
 
 
-  /*--------------------------------------.
-  | Binary functions, with their traits.  |
-  `--------------------------------------*/
+//   /*--------------------------------------.
+//   | Binary functions, with their traits.  |
+//   `--------------------------------------*/
 
-  // Fwd decl.
-  template <typename F>
-  class binary_function;
+//   // Fwd decl.
+//   template <typename F>
+//   class binary_function;
 
-  template <typename F>
-  struct function_traits< binary_function <F> >
-  {
-    static const int case_id = sizeof(fun_info_helper::on(make<F>::ptr()));
-    typedef typename fun_info<F, void, case_id>::argument1_type argument1_type;
-    typedef typename fun_info<F, void, case_id>::argument2_type argument2_type;
-    typedef typename fun_info<F, void, case_id>::result_type result_type;
-  };
+//   template <typename F>
+//   struct function_traits< binary_function <F> >
+//   {
+//     static const int case_id = sizeof(fun_info_helper::on(make<F>::ptr()));
+//     typedef typename fun_info<F, void, case_id>::argument1_type argument1_type;
+//     typedef typename fun_info<F, void, case_id>::argument2_type argument2_type;
+//     typedef typename fun_info<F, void, case_id>::result_type result_type;
+//   };
 
-  template <typename F>
-  class binary_function :
-    public mlc::abstract::binary_function< binary_function<F> >
-  {
-  public:
-    typedef binary_function<F> self_type;
-    typedef abstract::binary_function< binary_function<F> > super_type;
+//   template <typename F>
+//   class binary_function :
+//     public mlc::abstract::binary_function< binary_function<F> >
+//   {
+//   public:
+//     typedef binary_function<F> self_type;
+//     typedef abstract::binary_function< binary_function<F> > super_type;
 
-    typedef typename function_traits<self_type>::argument1_type argument1_type;
-    typedef typename function_traits<self_type>::argument2_type argument2_type;
-    typedef typename function_traits<self_type>::result_type result_type;
+//     typedef typename function_traits<self_type>::argument1_type argument1_type;
+//     typedef typename function_traits<self_type>::argument2_type argument2_type;
+//     typedef typename function_traits<self_type>::result_type result_type;
 
-  public:
-    binary_function(F f) : super_type(), f_(f)
-    {
-    }
+//   public:
+//     binary_function(F f) : super_type(), f_(f)
+//     {
+//     }
 
-    result_type
-    impl_op_paren (const argument1_type& arg1,
-		   const argument1_type& arg2) const
-    {
-      return f_(arg1, arg2);
-    }
+//     result_type
+//     impl_op_paren (const argument1_type& arg1,
+// 		   const argument1_type& arg2) const
+//     {
+//       return f_(arg1, arg2);
+//     }
 
-  private:
-    F f_;
-  };
+//   private:
+//     F f_;
+//   };
 
-  template <typename F>
-  binary_function<F>
-  make_binary_fun(F f)
-  {
-    return binary_function<F> (f);
-  }
+//   template <typename F>
+//   binary_function<F>
+//   make_binary_fun(F f)
+//   {
+//     return binary_function<F> (f);
+//   }
 
 
-  /*------------------------------------------.
-  | Meta-unary functions, with their traits.  |
-  `------------------------------------------*/
+//   /*------------------------------------------.
+//   | Meta-unary functions, with their traits.  |
+//   `------------------------------------------*/
 
-  // FIXME: To be re-enabled later.
-# if 0
-  template <typename F>
-  struct meta_fun_info
-  {
-    template <typename T>
-    struct with
-    {
-      static const case_id = sizeof(fun_info_helper::on(make<F>::ptr()));
-      typedef typename fun_info_result_type<F, T, case_id>::ret result_type;
-    };
-  };
-#endif
+//   // FIXME: To be re-enabled later.
+// # if 0
+//   template <typename F>
+//   struct meta_fun_info
+//   {
+//     template <typename T>
+//     struct with
+//     {
+//       static const case_id = sizeof(fun_info_helper::on(make<F>::ptr()));
+//       typedef typename fun_info_result_type<F, T, case_id>::ret result_type;
+//     };
+//   };
+// #endif
 
 
-} // end of namespace mlc
+// } // end of namespace mlc
 
 
 #endif // ! METALIC_FUN_HH
Index: mlc/afun.hh
===================================================================
--- mlc/afun.hh	(revision 268)
+++ mlc/afun.hh	(working copy)
@@ -31,7 +31,6 @@
 # include <mlc/any.hh>
 # include <mlc/contract.hh>
 # include <mlc/overload.hh>
-# include <mlc/properties.hh>
 # include <mlc/to_string.hh>
 
 
@@ -53,8 +52,6 @@
 namespace mlc
 {
 
-  mlc_equip_namespace_with_properties();
-
   mlc_decl_typedef(res_type);
   mlc_decl_typedef(arg_type);
   mlc_decl_typedef(arg1_type);
@@ -133,10 +130,8 @@
   };
 
 
-
-
   // traits for result type of meta functions.
-
+  
   template <typename F,
 	    typename A1,
 	    typename A2 = mlc::undefined_type,
@@ -147,24 +142,18 @@
   };
 
 
+  // tags used for overloading abstract::meta_*_function::operator().
 
-
-  // tags used for overloading abstract::*_function::operator().
-
-
   namespace tag
   {
-    // for meta functions
-    struct mufun; // unary
-    struct mbfun; // binary
-    struct mtfun; // ternary
-
+    struct mufun;
+    struct mbfun;
+    struct mtfun;
+    
   } // end of mlc::tag
 
 
 
-
-
   /// default impl of mlc::abstract::meta_unary_function<F>::operator()(const A&)
 
   template <typename F, typename A>
@@ -211,6 +200,7 @@
   template <typename F>
   struct set_props < category::fun, abstract::unary_function<F> >
   {
+    // typedef mlc::undefined_type arg_type;
     typedef mlc::no_type arg1_type;
     typedef mlc::no_type arg2_type;
     typedef mlc::no_type arg3_type;
@@ -220,6 +210,8 @@
   struct set_props < category::fun, abstract::binary_function<F> >
   {
     typedef mlc::no_type arg_type;
+    // typedef mlc::undefined_type arg1_type;
+    // typedef mlc::undefined_type arg2_type;
     typedef mlc::no_type arg3_type;
   };
 
@@ -227,6 +219,9 @@
   struct set_props < category::fun, abstract::ternary_function<F> >
   {
     typedef mlc::no_type arg_type;
+    // typedef mlc::undefined_type arg1_type;
+    // typedef mlc::undefined_type arg2_type;
+    // typedef mlc::undefined_type arg3_type;
   };
 
 
Index: mlc/bool.hh
===================================================================
--- mlc/bool.hh	(revision 268)
+++ mlc/bool.hh	(working copy)
@@ -106,6 +106,13 @@
   template <typename L, typename R> struct xor_  : public value <bool,   (mlc_bool(L) != mlc_bool(R)) > {};
   template <typename L, typename R> struct xnor_ : public value <bool, (!(mlc_bool(L) != mlc_bool(R)))> {};
 
+  // List of (imbricated) 'or_'.
+  // FIXME: instead of limited to three args, it should be variadic...
+
+  template <typename A1, typename A2, typename A3>
+  struct lor_ : public or_< or_<A1, A2>, A3 > {};
+
+
 } // end of namespace mlc
 
 
Index: mlc/typedef.hh
===================================================================
--- mlc/typedef.hh	(revision 268)
+++ mlc/typedef.hh	(working copy)
@@ -29,21 +29,28 @@
 # define METALIC_TYPEDEF_HH
 
 # include <mlc/types.hh>
+# include <mlc/bool.hh>
 
 
 // do not use the macro below if you equip a namespace with properties
 
-# define mlc_equip_namespace_with_typedef()		\
-namespace internal					\
-{							\
-  							\
-  template <typename type, typename typedef_type>	\
-  struct get_typedef					\
-  {							\
-    typedef mlc::internal::not_found ret;		\
-  };							\
-  							\
-}							\
+# define mlc_equip_namespace_with_typedef()				\
+namespace internal							\
+{									\
+									\
+  template <typename type, typename typedef_type>			\
+  struct get_typedef							\
+  {									\
+    typedef mlc::internal::not_found ret;				\
+  };									\
+									\
+  template <typename type, typename typedef_type, typename cond>	\
+  struct get_typedef_onlyif						\
+  {									\
+    typedef mlc::internal::not_found ret;				\
+  };									\
+									\
+}									\
 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
 
 
@@ -56,78 +63,176 @@
 ** FIXME
 */
 
-# define mlc_decl_typedef(TypedefName)						\
-namespace  internal								\
-{										\
-										\
-  namespace typedef_								\
-  {										\
-    struct TypedefName;								\
-  }										\
-										\
-  struct helper_get_typedef__##TypedefName					\
-  {										\
-    typedef char yes;								\
-    struct no { char tmp[2]; };							\
-										\
-    template <typename type, typename alias = typename type::TypedefName>	\
-    struct run_on;								\
-										\
-    template <typename type>							\
-    static yes selector(run_on<type>*);						\
-										\
-    template <typename type>							\
-    static no selector(...);							\
-										\
-    template <typename type, bool found>					\
-    struct result;								\
-										\
-    template <typename type>							\
-    struct result <type, true>							\
-    {										\
-      typedef typename type::TypedefName ret;					\
-    };										\
-										\
-    template <typename type>							\
-    struct result <type, false>							\
-    {										\
-      typedef mlc::internal::not_found ret;					\
-    };										\
-  };										\
-										\
-  template <typename type>							\
-  struct get_typedef__##TypedefName						\
-  {										\
-    typedef  helper_get_typedef__##TypedefName  helper_type;			\
-    static const bool found = ( sizeof(helper_type::selector<type>(0)) == 1 );	\
-    typedef typename helper_type::result<type, found>::ret ret;			\
-  };										\
-										\
-  template <typename type>							\
-  struct get_typedef <type, typedef_::TypedefName>				\
-  {										\
-    typedef typename get_typedef__##TypedefName <type> ::ret ret;		\
-  };										\
-										\
-}										\
+# define mlc_decl_typedef(TypedefName)							\
+namespace  internal									\
+{											\
+											\
+  namespace typedef_									\
+  {											\
+    struct TypedefName;									\
+  }											\
+											\
+  struct helper_get_typedef__##TypedefName						\
+  {											\
+    typedef char yes;									\
+    struct no { char tmp[2]; };								\
+											\
+    template <typename type, typename alias = typename type::TypedefName>		\
+    struct run_on;									\
+											\
+    template <typename type>								\
+    static yes selector(run_on<type>*);							\
+											\
+    template <typename type>								\
+    static no selector(...);								\
+											\
+    template <typename type, bool found>						\
+    struct result;									\
+											\
+    template <typename type>								\
+    struct result <type, true>								\
+    {											\
+      typedef typename type::TypedefName ret;						\
+    };											\
+											\
+    template <typename type>								\
+    struct result <type, false>								\
+    {											\
+      typedef mlc::internal::not_found ret;						\
+    };											\
+  };											\
+											\
+  template <typename type>								\
+  struct get_typedef__##TypedefName							\
+  {											\
+    typedef  helper_get_typedef__##TypedefName  helper_type;				\
+    static const bool found = ( sizeof(helper_type::selector<type>(0)) == 1 );		\
+    typedef typename helper_type::result<type, found>::ret ret;				\
+  };											\
+											\
+  template <typename type>								\
+  struct get_typedef <type, typedef_::TypedefName>					\
+  {											\
+    typedef typename get_typedef__##TypedefName <type> ::ret ret;			\
+  };											\
+											\
+											\
+  template <typename type, bool cond>							\
+  struct helper_get_typedef_onlyif__##TypedefName;					\
+											\
+  template <typename type>								\
+  struct helper_get_typedef_onlyif__##TypedefName <type, false>				\
+  {											\
+    typedef mlc::internal::not_ok ret;							\
+  };											\
+											\
+  template <typename type>								\
+  struct helper_get_typedef_onlyif__##TypedefName <type, true>				\
+  {											\
+    typedef typename type::TypedefName ret;						\
+  };											\
+											\
+  template <typename type, typename cond>						\
+  struct get_typedef_onlyif__##TypedefName						\
+    : public helper_get_typedef_onlyif__##TypedefName <type, mlc_bool(cond)>		\
+  {											\
+    typedef helper_get_typedef_onlyif__##TypedefName <type, mlc_bool(cond)> super;	\
+    using super::ret;									\
+  };											\
+											\
+  template <typename type, typename cond>						\
+  struct get_typedef_onlyif <type, typedef_::TypedefName, cond>				\
+  {											\
+    typedef typename get_typedef_onlyif__##TypedefName <type, cond> ::ret ret;		\
+  };											\
+											\
+											\
+}											\
 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
 
 
 
+// FIXME: mlc should be equipped for typedef retrieval
+// FIXME: and should provide at least facilities for 'ret'
 
+// namespace mlc
+// {
+//   mlc_equip_namespace_with_typedef();
+//   mlc_decl_typedef(ret);
+// } // end of namespace mlc
 
+
+
+
+// sample code to understand why mlc_typedef_onlyif_of is required
+// in particular situations:
+
+//     #include <mlc/typedef.hh>
+
+//     mlc_equip_namespace_with_typedef();
+//     mlc_decl_typedef(ret);
+
+//     struct toto
+//     {
+//       typedef float does_not_exist;
+//     };
+
+//     template <class T>
+//     struct ok
+//     {
+// 	 typedef double ret;
+// 	 typedef typename T::does_not_exist err;
+//     };
+
+//     template <class T>
+//     struct ko
+//     {
+//     };
+
+//     template <class T>
+//     void foo()
+//     {
+// 	 typedef mlc_typedef_of(T, ret) type;
+//     }
+
+//     template <class T, class B>
+//     void bar()
+//     {
+// 	 typedef mlc_typedef_onlyif_of(T, ret, B) type;
+//     }
+
+//     int main()
+//     {
+// 	 // code that does not compile:
+// 	 // foo< ok<int> >();
+// 	 // bar< ok<int>, mlc::true_type >();
+
+// 	 // code that works:
+// 	 foo< ok<toto> >();
+// 	 bar< ok<toto>, mlc::true_type >();
+// 	 bar< ok<int>, mlc::false_type >();
+//     }
+
+
 /*! \macro  mlc_typedef_of( FromType, TypedefName )
 **
 ** FIXME
 ** Sample use: mlc_typedef_of(std::vector<int>, value_type)
 */
 # define mlc_typedef_of_(FromType, TypedefName)		\
-							\
-internal::get_typedef__##TypedefName < FromType > ::ret
+internal::get_typedef__##TypedefName <FromType>::ret
 
+# define mlc_typedef_of(FromType, TypedefName)	\
+typename mlc_typedef_of_(FromType, TypedefName)
 
-# define mlc_typedef_of(FromType, TypedefName)  typename mlc_typedef_of_(FromType, TypedefName)
 
 
+# define mlc_typedef_onlyif_of_(FromType, TypedefName, Condition)	\
+internal::get_typedef_onlyif__##TypedefName <FromType, Condition>::ret
 
+# define mlc_typedef_onlyif_of(FromType, TypedefName, Condition)	\
+typename mlc_typedef_onlyif_of_(FromType, TypedefName, Condition)
+
+
+
 #endif // ! METALIC_TYPEDEF_HH
Index: mlc/flogic.hh
===================================================================
--- mlc/flogic.hh	(revision 268)
+++ mlc/flogic.hh	(working copy)
@@ -29,10 +29,69 @@
 # define METALIC_FLOGIC_HH
 
 # include <mlc/afun.hh>
+# include <mlc/ftraits.hh>
 
 
 
-# define mlc_decl_mfun_logic(OperatorName, OperatorBody)					\
+namespace mlc
+{
+  // sample uses:
+  //
+  // mlc::fun::and_<bool> f;
+  // f(b1, b2);
+  //
+  // mlc::fun::and_<bool, Boolean> f;
+  // f(b1, b2);
+  //
+  // mlc::f_and f;
+  // f(b1, b2);
+  // or directly:  mlc::f_and(b1, b2);
+
+
+
+  // The unary logic operator is 'not'.
+
+  namespace fun
+  {
+    template <typename T> struct not_;
+  }
+
+  template <typename T>
+  struct set_super_type < fun::not_<T> >
+  {
+    typedef abstract::unary_function< fun::not_<T> > ret;
+  };
+
+  template <typename T>
+  struct set_props < category::fun, fun::not_<T> >
+  {
+    typedef typename traits_not<T>::ret res_type;
+    typedef T arg_type;
+  };
+
+  namespace fun
+  {
+    template <typename T>
+    struct not_ : public mlc::abstract::unary_function< not_<T> >
+    {
+      typedef not_<T> self_type;
+      mlc_fun_type_of(self_type, res)
+      impl_unop(const T& arg) const
+      {
+	return not arg;
+      }
+    };
+  }
+
+  typedef mfun1<fun::not_> f_not_type;
+  static f_not_type f_not;
+
+} // end of namespace mlc
+
+
+
+
+# define mlc_decl_fun_binary_logic(OperatorName, OperatorBody)					\
 												\
   namespace fun											\
   {												\
@@ -48,17 +107,19 @@
   template <typename T1, typename T2>								\
   struct set_props < category::fun, fun::OperatorName##_<T1,T2> >				\
   {												\
-    typedef bool res_type;									\
+    typedef typename traits_##OperatorName<T1,T2>::ret res_type;				\
     typedef T1 arg1_type;									\
     typedef T2 arg2_type;									\
   };												\
 												\
   namespace fun											\
   {												\
-    template <typename T1, typename T2>								\
+    template <typename T1, typename T2 = T1>							\
     struct OperatorName##_ : public mlc::abstract::binary_function< OperatorName##_<T1,T2> >	\
     {												\
-      bool impl_binop(const T1& lhs, const T2& rhs) const					\
+      typedef OperatorName##_<T1,T2> self_type;							\
+      mlc_fun_type_of(self_type, res)								\
+      impl_binop(const T1& lhs, const T2& rhs) const						\
       {												\
 	return OperatorBody;									\
       }												\
@@ -72,17 +133,19 @@
 
 
 
+// Binary logic operators.
+
 namespace mlc
 {
 
-  mlc_decl_mfun_logic(   and,       lhs and rhs  );
-  mlc_decl_mfun_logic(  nand,  not (lhs and rhs) );
+  mlc_decl_fun_binary_logic(   and,       lhs and rhs  );
+  mlc_decl_fun_binary_logic(  nand,  not (lhs and rhs) );
 
-  mlc_decl_mfun_logic(    or,       lhs or rhs  );
-  mlc_decl_mfun_logic(   nor,  not (lhs or rhs) );
+  mlc_decl_fun_binary_logic(    or,       lhs or rhs  );
+  mlc_decl_fun_binary_logic(   nor,  not (lhs or rhs) );
 
-  mlc_decl_mfun_logic(   xor,  (lhs and not rhs) or (not lhs and     rhs) );
-  mlc_decl_mfun_logic(  xnor,  (lhs and     rhs) or (not lhs and not rhs) );
+  mlc_decl_fun_binary_logic(   xor,  (lhs and not rhs) or (not lhs and     rhs) );
+  mlc_decl_fun_binary_logic(  xnor,  (lhs and     rhs) or (not lhs and not rhs) );
 
 } // end of namespace mlc
 
Index: mlc/makefile.src
===================================================================
--- mlc/makefile.src	(revision 268)
+++ mlc/makefile.src	(working copy)
@@ -21,8 +21,10 @@
   cmp.hh					\
   config/system.hh				\
   contract.hh					\
+  farith.hh					\
   fcmp.hh					\
   flogic.hh					\
+  ftraits.hh					\
   fun.hh					\
   if.hh						\
   implies.hh					\
@@ -33,7 +35,6 @@
   switch.hh					\
   to_string.hh					\
   tracked_ptr.hh				\
-  traits.hh					\
   typedef.hh					\
   types.hh					\
   value.hh
Index: mlc/traits.hh
===================================================================
--- mlc/traits.hh	(revision 268)
+++ mlc/traits.hh	(working copy)
@@ -1,37 +0,0 @@
-// Copyright (C) 2005 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library.  This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING.  If not, write to
-// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-// MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction.  Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License.  This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef METALIC_TRAITS_HH
-# define METALIC_TRAITS_HH
-
-
-// FIXME: this file contents seemed useless so it has been removed!
-// FIXME: remove also this file?
-
-
-
-#endif // ! METALIC_TRAITS_HH
Index: mlc/overload.hh
===================================================================
--- mlc/overload.hh	(revision 268)
+++ mlc/overload.hh	(working copy)
@@ -33,11 +33,16 @@
 # include <mlc/is_a.hh>
 # include <mlc/if.hh>
 # include <mlc/cmp.hh>
+# include <mlc/typedef.hh>
+# include <mlc/properties.hh>
 
 
 namespace mlc
 {
 
+  mlc_equip_namespace_with_properties();
+
+
   /// where (for use as where clause).
 
   template <typename B>
@@ -53,10 +58,12 @@
   template <typename what_is_overloaded,
  	    unsigned i,
 	    typename T1,
-	    typename T2 = mlc::undefined_type,
-	    typename T3 = mlc::undefined_type>
-  struct decl_overload : public mlc::undefined_type
-  {};
+	    typename T2 = no_type,
+	    typename T3 = no_type>
+  struct decl_overload : public undefined_type // FIXME: undefined_type is obsolete here
+  {
+    // no 'ret' inside
+  };
 
   // we know that the structure above is specialized by a client when
   // it does not derive from mlc::undefined_type
@@ -69,13 +76,15 @@
   {
 
     template <typename what, unsigned i,
-	      typename T1, typename T2, typename T3>
+	      typename T1,
+	      typename T2 = no_type,
+	      typename T3 = no_type>
     struct f_overload;
 
     // f_overload(i)  ---here, other params are omitted
     // {
     //   for i = 1...
-    //     if (decl_overload(i) derives from undefined_type)
+    //     if (decl_overload(i) has not "typedef ret")
     //       ---default case
     //       return decl_overload(0)
     //     else if (decl_overload(i) derives from true_type)
@@ -96,7 +105,7 @@
 
     template <typename what, unsigned i,
 	      typename T1, typename T2, typename T3>
-    struct helper_f_overload <mlc::undefined_type,
+    struct helper_f_overload <undefined_type,
 			      what, i, T1,T2,T3>
     {
       typedef decl_overload<what, 0, T1,T2,T3> ret;
@@ -106,7 +115,7 @@
 
     template <typename what, unsigned i,
 	      typename T1, typename T2, typename T3>
-    struct helper_f_overload <mlc::true_type,
+    struct helper_f_overload <true_type,
 			      what, i, T1,T2,T3>
     {
       typedef decl_overload<what, i, T1,T2,T3> ret;
@@ -116,10 +125,11 @@
 
     template <typename what, unsigned i,
 	      typename T1, typename T2, typename T3>
-    struct helper_f_overload <mlc::false_type,
+    struct helper_f_overload <false_type,
 			      what, i, T1,T2,T3>
     {
-      typedef typename f_overload<what, i+1, T1,T2,T3>::ret ret;
+      typedef f_overload<what, i+1, T1,T2,T3> next_overload;
+      typedef typename next_overload::ret ret;
     };
 
     // f_overload
@@ -129,14 +139,33 @@
     struct f_overload
     {
       typedef decl_overload<what, i, T1,T2,T3> decl;
+
+//       first version of meta-code:
+//       ---------------------------
+//       typedef typename
+//       if_< mlc_is_a(decl, undefined_type),
+// 	   undefined_type, typename
+// 	   if_< mlc_is_a(decl, true_type),
+// 		true_type,
+// 		false_type >::ret
+//       >::ret base;
+
+//       new version relying on mlc_typedef_of:
+//       --------------------------------------
+      typedef mlc_typedef_of(decl, ret) decl_ret;
+
+//       typedef eq<decl_ret, mlc::internal::not_found> eq_res;
+//       typedef false_type base;
       typedef typename
-      mlc::if_< mlc_is_a(decl, mlc::undefined_type),
-		mlc::undefined_type, typename
-		mlc::if_< mlc_is_a(decl, mlc::true_type),
-			  mlc::true_type,
-			  mlc::false_type >::ret
+      if_< eq<decl_ret, mlc::internal::not_found>,
+	   undefined_type, typename
+	   if_< mlc_is_a(decl, true_type),
+		true_type,
+		false_type >::ret
       >::ret base;
-      typedef typename helper_f_overload<base, what, i, T1,T2,T3>::ret ret;
+
+      typedef helper_f_overload<base, what, i, T1,T2,T3> helper;
+      typedef typename helper::ret ret;
     };
 
   } // end of namespace mlc::internal
@@ -146,15 +175,15 @@
 
   template <typename what,
 	    typename T1,
-	    typename T2 = mlc::undefined_type,
-	    typename T3 = mlc::undefined_type>
+	    typename T2 = no_type,
+	    typename T3 = no_type>
   struct overload
   {
     static const unsigned start = 1;
     typedef typename internal::f_overload<what, start, T1,T2,T3>::ret overload_type;
 
     // ret
-    typedef typename overload_type::ret ret;
+    typedef mlc_typedef_of(overload_type, ret) ret;
 
     // exec
     static ret exec(const T1& arg1, const T2& arg2, const T3& arg3)
@@ -170,15 +199,15 @@
 	    typename T1, typename T2>
   struct overload <what,
 		   T1, T2,
-		   mlc::undefined_type>
+		   no_type>
   {
-    typedef mlc::undefined_type T3;
+    typedef no_type T3;
 
     static const unsigned start = 1;
     typedef typename internal::f_overload<what, start, T1,T2,T3>::ret overload_type;
 
     // ret
-    typedef typename overload_type::ret ret;
+    typedef mlc_typedef_of(overload_type, ret) ret;
 
     // exec
     static ret exec(const T1& arg1, const T2& arg2)
@@ -194,16 +223,16 @@
 	    typename T1>
   struct overload <what,
 		   T1,
-		   mlc::undefined_type, mlc::undefined_type>
+		   no_type, no_type>
   {
-    typedef mlc::undefined_type T2;
-    typedef mlc::undefined_type T3;
+    typedef no_type T2;
+    typedef no_type T3;
 
     static const unsigned start = 1;
     typedef typename internal::f_overload<what, start, T1,T2,T3>::ret overload_type;
 
     // ret
-    typedef typename overload_type::ret ret;
+    typedef mlc_typedef_of(overload_type, ret) ret;
 
     // exec
     static ret exec(const T1& arg1)
@@ -227,7 +256,7 @@
 }
 
 template <class T>
-struct decl_overload <tag::foo, 1, T> : public where< mlc::eq<T, int> >
+struct decl_overload <tag::foo, 1, T> : public where< eq<T, int> >
 {
   typedef int ret;
   static ret exec(const int& lhs)
Index: mlc/ftraits.hh
===================================================================
--- mlc/ftraits.hh	(revision 0)
+++ mlc/ftraits.hh	(revision 0)
@@ -0,0 +1,498 @@
+// Copyright (C) 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef METALIC_FTRAITS_HH
+# define METALIC_FTRAITS_HH
+
+# include <mlc/types.hh>
+# include <mlc/bool.hh>
+# include <mlc/cmp.hh>
+# include <mlc/typedef.hh>
+# include <mlc/overload.hh>
+
+
+// FIXME: libraries should be id-ed in a different way...
+
+namespace mlc
+{
+  enum {
+    // FIXME: add builtin_id = 1 and update code below...
+    ntg_id = 2,
+    oln_id = 3
+  };
+} // end of namespace mlc
+
+
+
+
+
+// Macro mlc_decl_unary_traits.
+
+# define mlc_decl_unary_traits(Name)				\
+								\
+  namespace tag { struct Name##_; }				\
+								\
+  template <typename T>						\
+  struct unary_traits <tag::Name##_, T>				\
+  {								\
+    typedef typename overload<tag::Name##_, T>::ret ret;	\
+  };								\
+								\
+  template <typename T>						\
+  struct traits_##Name : public unary_traits<tag::Name##_, T>	\
+  {								\
+  };								\
+								\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+# define mlc_decl_unary_arith_builtin_traits(Name)	\
+							\
+  mlc_decl_unary_traits(Name);				\
+							\
+  template <typename T>					\
+  struct decl_overload <tag::Name##_, 1, T>		\
+    : public where< is_builtin<T> >			\
+  {							\
+    typedef T ret;					\
+  };							\
+							\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+// Macro mlc_decl_binary_traits.
+
+# define mlc_decl_binary_traits(Name)					\
+									\
+  namespace tag { struct Name##_; }					\
+									\
+  template <typename T1, typename T2>					\
+  struct binary_traits <tag::Name##_, T1, T2>				\
+  {									\
+    typedef typename overload<tag::Name##_, T1, T2>::ret ret;		\
+  };									\
+									\
+  template <typename T1, typename T2>					\
+  struct traits_##Name : public binary_traits<tag::Name##_, T1, T2>	\
+  {									\
+  };									\
+									\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+// FIXME: what about binary traits with a single type; e.g., for min<T,T>?
+// FIXME: is the code below ok?
+
+// Macro mlc_decl_mono_binary_traits.
+
+# define mlc_decl_mono_binary_traits(Name)				\
+									\
+  namespace tag { struct Name##_; }					\
+									\
+  template <typename T1, typename T2>					\
+  struct binary_traits <tag::Name##_, T1, T2>				\
+  {									\
+    typedef typename overload<tag::Name##_, T1, T2>::ret ret;		\
+  };									\
+									\
+  template <typename T1, typename T2>					\
+  struct traits_##Name : public binary_traits<tag::Name##_, T1, T2>	\
+  {									\
+  };									\
+									\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+
+// Macro mlc_decl_binary_arith_builtin_traits.
+
+# define mlc_decl_binary_arith_builtin_traits(Name)		\
+								\
+  mlc_decl_binary_traits(Name);					\
+								\
+  template <typename T1, typename T2>				\
+  struct decl_overload <tag::Name##_, 1, T1, T2>		\
+    : public where< and_< is_builtin<T1>, is_builtin<T2> > >	\
+  {								\
+    typedef overload<internal::tag_UAC, T1, T2> type;		\
+    typedef and_< is_builtin<T1>, is_builtin<T2> > cond;	\
+    typedef mlc_typedef_onlyif_of(type, ret, cond) ret;		\
+  };								\
+								\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+// Macro mlc_decl_mono_binary_builtin_traits.
+// FIXME: simplistic and wrong code... change!
+
+# define mlc_decl_mono_binary_builtin_traits(Name)		\
+								\
+  mlc_decl_mono_binary_traits(Name);				\
+								\
+  template <typename T1, typename T2>				\
+  struct decl_overload <tag::Name##_, 1, T1, T2>		\
+    : public where< and_< is_builtin<T1>, is_builtin<T2> > >	\
+  {								\
+    typedef T1 ret;						\
+  };								\
+								\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+
+
+
+// Macro mlc_decl_unary_logic_builtin_traits.
+
+# define mlc_decl_unary_logic_builtin_traits(Name)	\
+							\
+  mlc_decl_unary_traits(Name);				\
+							\
+  template <typename T>					\
+  struct decl_overload <tag::Name##_, 1, T>		\
+    : public where< is_builtin<T> >			\
+  {							\
+    typedef bool ret;					\
+  };							\
+							\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+// Macro mlc_decl_binary_logic_builtin_traits.
+
+// FIXME: rule 2 should return either T1 or T2
+// FIXME: rule 2 should ensure that both types are Boolean
+
+# define mlc_decl_binary_logic_builtin_traits(Name)					\
+											\
+  mlc_decl_binary_traits(Name);								\
+											\
+  template <typename T1, typename T2>							\
+  struct decl_overload <tag::Name##_, 1, T1, T2>					\
+    : public where< and_< is_builtin<T1>, is_builtin<T2> > >				\
+  {											\
+    typedef bool ret;									\
+  };											\
+											\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+
+// Macro mlc_decl_cmp_builtin_traits.
+
+# define mlc_decl_cmp_builtin_traits mlc_decl_binary_logic_builtin_traits
+
+
+
+
+
+# define mlc_intprom(TYPE) typename mlc::internal::integral_promote<TYPE>::ret
+
+
+
+
+# define mlc_decl_is(QUALIFIER, TYPE)				\
+								\
+  template <>							\
+  struct is_##QUALIFIER <TYPE> : public value<bool, true>	\
+  {								\
+  protected:							\
+    is_##QUALIFIER() {}						\
+  };								\
+								\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+namespace mlc
+{
+
+  template <typename Tag, typename T>
+  struct unary_traits
+  {
+  };
+
+  template <typename Tag, typename T1, typename T2>
+  struct binary_traits
+  {
+  };
+
+
+  // identification of built-in types
+
+  template <typename T>
+  struct is_builtin : public value<bool, false>
+  {
+  protected:
+    is_builtin() {}
+  };
+
+  mlc_decl_is( builtin,          bool   );
+
+  mlc_decl_is( builtin,          float  );
+  mlc_decl_is( builtin,          double );
+  mlc_decl_is( builtin,     long double );
+
+  mlc_decl_is( builtin,          char   );
+  mlc_decl_is( builtin, unsigned char   );
+  mlc_decl_is( builtin,   signed char   );
+
+  mlc_decl_is( builtin, unsigned short );
+  mlc_decl_is( builtin,   signed short );
+  mlc_decl_is( builtin, unsigned int   );
+  mlc_decl_is( builtin,   signed int   );
+  mlc_decl_is( builtin, unsigned long  );
+  mlc_decl_is( builtin,   signed long  );
+
+
+  // identification of arrays
+
+  template <typename T>
+  struct is_array : public value<bool, false>
+  {
+  protected:
+    is_array() {}
+  };
+
+  template <typename T, unsigned n>
+  struct is_array <T[n]> : public value<bool, true>
+  {
+  protected:
+    is_array() {}
+  };
+
+
+  // identification of Boolean value types
+
+  template <typename T>
+  struct is_Boolean : public value<bool, false>
+  {
+  protected:
+    is_Boolean() {}
+  };
+
+  mlc_decl_is( Boolean, bool );
+
+
+
+  // traits
+
+  template <typename Tag, typename T1, typename T2 = no_type>
+  struct traits
+  {
+    typedef typename overload<Tag, T1, T2>::ret ret;
+  };
+
+
+  // built-in traits and usual arithmetic conversions
+
+  namespace internal
+  {
+
+    // FIXME:... Cf. page 90 du pdf de la norme...
+
+
+    struct tag_UAC; // for "usual arithmetic conversions"
+
+    // Integral promotion such as defined in FIXME: std.
+
+    template <class T>
+    struct integral_promote
+    {
+      typedef T ret;
+    };
+
+    // FIXME: approx?
+
+    template <> struct integral_promote <char> { typedef int ret; };
+    template <> struct integral_promote <signed char> { typedef int ret; };
+    template <> struct integral_promote <unsigned char> { typedef int ret; };
+    template <> struct integral_promote <unsigned short int> { typedef int ret; };
+
+    template <> struct integral_promote <bool> { typedef int ret; }; // FIXME: right?
+
+  } // end of namespace mlc::internal
+
+
+  // 1) Prevent bool to be involved in arithmetics.
+  template <typename T1, typename T2>
+  struct decl_overload <internal::tag_UAC, 1, T1, T2>
+    : where< or_<eq<T1, bool>, eq<T2, bool> > >
+  {
+    typedef undefined_type ret;
+  };
+
+  // 2) If either operand is of type long double, the other shall be
+  // 2) converted to long double.
+  template <typename T1, typename T2>
+  struct decl_overload <internal::tag_UAC, 2, T1, T2>
+    : where< or_<eq<T1, long double>, eq<T2, long double> > >
+  {
+    typedef long double ret;
+  };
+
+  // 3) Otherwise, if either operand is double, the other shall be
+  // 3) converted to double.
+  template <typename T1, typename T2>
+  struct decl_overload <internal::tag_UAC, 3, T1, T2>
+    : where< or_<eq<T1, double>, eq<T2, double> > >
+  {
+    typedef double ret;
+  };
+
+  // 4) Otherwise, if either operand is float, the other shall be
+  // 4) converted to float.
+  template <typename T1, typename T2>
+  struct decl_overload <internal::tag_UAC, 4, T1, T2>
+    : where< or_<eq<T1, float>, eq<T2, float> > >
+  {
+    typedef float ret;
+  };
+  
+  // 5) If either operand is unsigned long the other shall be
+  // 5) converted to unsigned long.
+  template <typename T1, typename T2>
+  struct decl_overload <internal::tag_UAC, 5, T1, T2>
+    : where< or_<eq<T1, unsigned long>, eq<T2, unsigned long> > >
+  {
+    typedef unsigned long ret;
+  };
+  
+  // 6) Otherwise, if one operand is a long int and the other unsigned
+  // 6) int, then if a long int can represent all the values of an
+  // 6) unsigned int, the unsigned int shall be converted to a long
+  // 6) int; otherwise both operands shall be converted to unsigned
+  // 6) long int.
+  template <typename T1, typename T2>
+  struct decl_overload <internal::tag_UAC, 6, T1, T2>
+    : where< or_< and_< eq<mlc_intprom(T1), long int>,
+			eq<mlc_intprom(T2), unsigned int> >,
+		  and_< eq<mlc_intprom(T2), long int>,
+			eq<mlc_intprom(T1), unsigned int> > > >
+  {
+    typedef long int ret; // FIXME: approx...
+  };
+
+  // 7) Otherwise, if either operand is long, the other shall be
+  // 7) converted to long.
+  template <typename T1, typename T2>
+  struct decl_overload <internal::tag_UAC, 7, T1, T2>
+    : where< or_<eq<mlc_intprom(T1), long>, eq<mlc_intprom(T2), long> > >
+  {
+    typedef long ret;
+  };
+
+  // 8) Otherwise, if either operand is unsigned, the other shall be
+  // 8) converted to unsigned.
+  template <typename T1, typename T2>
+  struct decl_overload <internal::tag_UAC, 8, T1, T2>
+    : where< or_<eq<mlc_intprom(T1), unsigned>, eq<mlc_intprom(T2), unsigned> > >
+  {
+    typedef unsigned ret;
+  };
+
+  // 0) Note: otherwise, the only remaining case is that both operands
+  // 0) are int.
+  template <typename T1, typename T2>
+  struct decl_overload <internal::tag_UAC, 0, T1, T2>
+  {
+    // FIXME: test that:
+    // or_<eq<mlc_intprom(T1), int>, eq<mlc_intprom(T2), int> >
+    typedef int ret;
+  };
+
+
+  // Arith.
+
+  mlc_decl_unary_traits( uminus );
+
+  template <typename T>
+  struct decl_overload <tag::uminus_, 1, T>
+    : public where< is_builtin<T> >
+  {
+    typedef mlc_intprom(T) ret; // FIXME: correct?
+    // FIXME: is it relevant to check that the result is traits_minus<int,T>::ret?
+  };
+
+  mlc_decl_unary_arith_builtin_traits( inc );
+  mlc_decl_unary_arith_builtin_traits( dec );
+
+  mlc_decl_binary_arith_builtin_traits( plus  );
+  mlc_decl_binary_arith_builtin_traits( minus );
+  mlc_decl_binary_arith_builtin_traits( times );
+  mlc_decl_binary_arith_builtin_traits( div   );
+  mlc_decl_binary_arith_builtin_traits( mod   );
+  
+
+  // Logic.
+
+  mlc_decl_unary_logic_builtin_traits(   not );
+  
+  mlc_decl_binary_logic_builtin_traits(  and );
+  mlc_decl_binary_logic_builtin_traits( nand );
+  mlc_decl_binary_logic_builtin_traits(   or );
+  mlc_decl_binary_logic_builtin_traits(  nor );
+  mlc_decl_binary_logic_builtin_traits(  xor );
+  mlc_decl_binary_logic_builtin_traits( xnor );
+
+
+  // Cmp.
+
+  mlc_decl_cmp_builtin_traits(  eq );
+  mlc_decl_cmp_builtin_traits( neq );
+  mlc_decl_cmp_builtin_traits( less );
+  mlc_decl_cmp_builtin_traits( leq );
+  mlc_decl_cmp_builtin_traits( greater );
+  mlc_decl_cmp_builtin_traits( geq );
+
+
+  // Mono binary.
+
+  mlc_decl_mono_binary_builtin_traits(min);
+  mlc_decl_mono_binary_builtin_traits(max);
+  mlc_decl_mono_binary_builtin_traits(inf);
+  mlc_decl_mono_binary_builtin_traits(sup);
+
+
+} // end of namespace mlc
+
+
+# define mlc_binary_ret_(OperatorName, T1, T2) mlc::traits_##OperatorName <T1,T2>::ret
+# define mlc_binary_ret(OperatorName, T1, T2) typename mlc_binary_ret_(OperatorName, T1, T2)
+
+# define mlc_unary_ret_(OperatorName, T) mlc::traits_##OperatorName <T>::ret
+# define mlc_unary_ret(OperatorName, T) typename mlc_unary_ret_(OperatorName, T)
+
+
+
+#endif // ! METALIC_FTRAITS_HH
Index: mlc/farith.hh
===================================================================
--- mlc/farith.hh	(revision 0)
+++ mlc/farith.hh	(revision 0)
@@ -0,0 +1,158 @@
+// Copyright (C) 2005  EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef METALIC_FARITH_HH
+# define METALIC_FARITH_HH
+
+# include <mlc/afun.hh>
+# include <mlc/ftraits.hh>
+
+# include <algorithm>
+
+
+
+/// Macro mlc_decl_fun_unary_arith.
+
+# define mlc_decl_fun_unary_arith(OperatorName, OperatorBody)				\
+											\
+  namespace fun										\
+  {											\
+    template <typename T> struct OperatorName##_;					\
+  }											\
+											\
+  template <typename T>									\
+  struct set_super_type < fun::OperatorName##_<T> >					\
+  {											\
+    typedef abstract::unary_function< fun::OperatorName##_<T> > ret;			\
+  };											\
+											\
+  template <typename T>									\
+  struct set_props < category::fun, fun::OperatorName##_<T> >				\
+  {											\
+    typedef typename traits_##OperatorName<T>::ret res_type;				\
+    typedef T arg_type;									\
+  };											\
+											\
+  namespace fun										\
+  {											\
+    template <typename T>								\
+    struct OperatorName##_ : public mlc::abstract::unary_function< OperatorName##_<T> >	\
+    {											\
+      typedef OperatorName##_<T> self_type;						\
+      mlc_fun_type_of(self_type, res)							\
+      impl_unop(const T& arg) const							\
+      {											\
+	return OperatorBody;								\
+      }											\
+    };											\
+  }											\
+											\
+  typedef mfun1<fun::OperatorName##_> f_##OperatorName##_type;				\
+  static f_##OperatorName##_type f_##OperatorName;					\
+											\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+/// Macro mlc_decl_fun_binary_arith.
+
+# define mlc_decl_fun_binary_arith(OperatorName, OperatorBody)					\
+												\
+  namespace fun											\
+  {												\
+    template <typename T1, typename T2> struct OperatorName##_;					\
+  }												\
+												\
+  template <typename T1, typename T2>								\
+  struct set_super_type < fun::OperatorName##_<T1,T2> >						\
+  {												\
+    typedef abstract::binary_function< fun::OperatorName##_<T1,T2> > ret;			\
+  };												\
+												\
+  template <typename T1, typename T2>								\
+  struct set_props < category::fun, fun::OperatorName##_<T1,T2> >				\
+  {												\
+    typedef typename traits_##OperatorName<T1,T2>::ret res_type;				\
+    typedef T1 arg1_type;									\
+    typedef T2 arg2_type;									\
+  };												\
+												\
+  namespace fun											\
+  {												\
+    template <typename T1, typename T2 = T1>							\
+    struct OperatorName##_ : public mlc::abstract::binary_function< OperatorName##_<T1,T2> >	\
+    {												\
+      typedef OperatorName##_<T1,T2> self_type;							\
+      mlc_fun_type_of(self_type, res)								\
+      impl_binop(const T1& lhs, const T2& rhs) const						\
+      {												\
+	return OperatorBody;									\
+      }												\
+    };												\
+  }												\
+												\
+  typedef mfun2<fun::OperatorName##_> f_##OperatorName##_type;					\
+  static f_##OperatorName##_type f_##OperatorName;						\
+												\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+namespace mlc
+{
+  // FIXME: update... sample uses:
+  //
+  // mlc::fun::and_<bool> f;
+  // f(b1, b2);
+  //
+  // mlc::fun::and_<bool, Boolean> f;
+  // f(b1, b2);
+  //
+  // mlc::f_and f;
+  // f(b1, b2);
+  // or directly:  mlc::f_and(b1, b2);
+
+  mlc_decl_fun_unary_arith(  inc,    ++arg );
+  mlc_decl_fun_unary_arith(  dec,    --arg );
+  mlc_decl_fun_unary_arith(  uminus, - arg );
+
+  mlc_decl_fun_binary_arith( plus,  lhs + rhs );
+  mlc_decl_fun_binary_arith( minus, lhs - rhs );
+  mlc_decl_fun_binary_arith( times, lhs * rhs );
+  mlc_decl_fun_binary_arith( div,   lhs / rhs );
+  mlc_decl_fun_binary_arith( mod,   lhs % rhs );
+
+  mlc_decl_fun_binary_arith( min,   (std::min<T1>(lhs, rhs)) );
+  mlc_decl_fun_binary_arith( max,   (std::max<T1>(lhs, rhs)) );
+  mlc_decl_fun_binary_arith( inf,   (std::min<T1>(lhs, rhs)) ); // FIXME: awful!
+  mlc_decl_fun_binary_arith( sup,   (std::max<T1>(lhs, rhs)) ); // FIXME: awful!
+
+} // end of namespace mlc
+
+
+
+#endif // ! METALIC_FARITH_HH
Index: mlc/array/1d.hh
===================================================================
--- mlc/array/1d.hh	(revision 268)
+++ mlc/array/1d.hh	(working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2001, 2002, 2003, 2004  EPITA Research and Development Laboratory
+// Copyright (C) 2001, 2002, 2003, 2004, 2005  EPITA Research and Development Laboratory
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -31,8 +31,11 @@
 # include <mlc/contract.hh>
 # include <mlc/arith.hh>
 # include <mlc/array/objs.hh>
-# include <ntg/basics.hh>
+# include <mlc/ftraits.hh>
+# include <mlc/to_string.hh>
+
 # include <iostream>
+# include <cmath>
 
 
 // impl
@@ -41,7 +44,21 @@
 namespace mlc
 {
 
+  // fwd decl
   template<class Info_, class T_>
+  struct array1d;
+
+  // binary traits
+  template <class Tag, class Info_, class T_, class U>
+  struct binary_traits <Tag, array1d<Info_, T_>, U>
+  {
+    typedef typename binary_traits<Tag, T_, U>::ret V;
+    typedef array1d<Info_, V> ret;
+  };
+
+
+
+  template<class Info_, class T_>
   struct array1d
   {
     typedef array1d self;
@@ -85,7 +102,7 @@
     static std::string
     name()
     {
-      return std::string("array1d< Info, ") + ntg_name(T) + " >";
+      return std::string("array1d< Info, ") + mlc_to_string(T) + " >";
     }
 
 
@@ -96,12 +113,12 @@
 
     // Normalize (absolute values -> relative values)
 
-    array1d<Info_, ntg::float_s>
+    array1d<Info_, float>
     normalize()
     {
-      array1d<Info_, ntg::float_s> tmp;
-      ntg::float_s sum = 0.f;
-      const ntg::float_s epsilon = 0.01f; // FIXME : epsilon should be global
+      array1d<Info_, float> tmp;
+      float sum = 0.f;
+      const float epsilon = 0.01f; // FIXME : epsilon should be global
       unsigned i;
       for (i = 0; i < Info_::card; ++i)
 	sum += this->buffer_[i];
@@ -137,20 +154,20 @@
     // Think of a mechanism similar to apply() and apply2().
 
     template <class U>
-    array1d< Info, ntg_return_type(times, T, U) >
+    array1d< Info, mlc_binary_ret(times, T, U) >
     operator*(U w)
     {
-      array1d< Info, ntg_return_type(times, T, U) > tmp;
+      array1d< Info, mlc_binary_ret(times, T, U) > tmp;
       for (unsigned i = 0; i < Info::card; ++i)
 	tmp[i] = this->buffer_[i] * w;
       return tmp;
     }
 
     template <class U>
-    array1d< Info, ntg_return_type(div, T, U) >
+    array1d< Info, mlc_binary_ret(div, T, U) >
     operator/(U w)
     {
-      array1d< Info, ntg_return_type(div, T, U) > tmp;
+      array1d< Info, mlc_binary_ret(div, T, U) > tmp;
       for (unsigned i = 0; i < Info::card; ++i)
 	tmp[i] = this->buffer_[i] / w;
       return tmp;
Index: mlc/array/2d.hh
===================================================================
--- mlc/array/2d.hh	(revision 268)
+++ mlc/array/2d.hh	(working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2001, 2002, 2003, 2004  EPITA Research and Development Laboratory
+// Copyright (C) 2001, 2002, 2003, 2004, 2005  EPITA Research and Development Laboratory
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -31,9 +31,11 @@
 # include <mlc/array/objs.hh>
 # include <mlc/contract.hh>
 # include <mlc/arith.hh>
-# include <ntg/basics.hh>
+# include <mlc/ftraits.hh>
+# include <mlc/to_string.hh>
 
 # include <iostream>
+# include <cmath>
 
 // impl
 # include <mlc/array/2d.hxx>
@@ -41,7 +43,20 @@
 namespace mlc
 {
 
+  // fwd decl
   template<class Info_, class T_>
+  struct array2d;
+
+  // binary traits
+  template <class Tag, class Info_, class T_, class U>
+  struct binary_traits <Tag, array2d<Info_, T_>, U>
+  {
+    typedef typename binary_traits<Tag, T_, U>::ret V;
+    typedef array2d<Info_, V> ret;
+  };
+
+
+  template<class Info_, class T_>
   struct array2d
   {
     typedef array2d self;
@@ -85,7 +100,7 @@
     static std::string
     name()
     {
-      return std::string("array2d< Info, ") + ntg_name(T) + " >";
+      return std::string("array2d< Info, ") + mlc_to_string(T) + " >";
     }
 
 
@@ -97,12 +112,12 @@
 
     // Normalize (absolute values -> relative values)
 
-    array2d<Info_, ntg::float_s>
+    array2d<Info_, float>
     normalize()
     {
-      array2d<Info_, ntg::float_s> tmp;
-      ntg::float_s sum = 0.f;
-      const ntg::float_s epsilon = 0.01f; // FIXME : epsilon should be global
+      array2d<Info_, float> tmp;
+      float sum = 0.f;
+      const float epsilon = 0.01f; // FIXME : epsilon should be global
       unsigned i;
       for (i = 0; i < Info_::card; ++i)
 	sum += this->buffer_[i];
@@ -112,7 +127,7 @@
       sum = 0.f;
       for (i = 0; i < Info_::card; ++i)
 	sum += tmp[i];
-      postcondition(std::abs(sum - 1) <= epsilon);
+      postcondition(std::fabs(sum - 1) <= epsilon);
       return tmp;
     }
 
@@ -156,20 +171,20 @@
     // Think of a mechanism similar to apply() and apply2().
 
     template <class U>
-    array2d< Info, ntg_return_type(times, T, U) >
+    array2d< Info, mlc_binary_ret(times, T, U) >
     operator*(U w)
     {
-      array2d< Info, ntg_return_type(times, T, U) > tmp;
+      array2d< Info, mlc_binary_ret(times, T, U) > tmp;
       for (unsigned i = 0; i < Info::card; ++i)
 	tmp[i] = this->buffer_[i] * w;
       return tmp;
     }
 
     template <class U>
-    array2d< Info, ntg_return_type(div, T, U) >
+    array2d< Info, mlc_binary_ret(div, T, U) >
     operator/(U w)
     {
-      array2d< Info, ntg_return_type(div, T, U) > tmp;
+      array2d< Info, mlc_binary_ret(div, T, U) > tmp;
       for (unsigned i = 0; i < Info::card; ++i)
 	tmp[i] = this->buffer_[i] / w;
       return tmp;
Index: mlc/array/3d.hh
===================================================================
--- mlc/array/3d.hh	(revision 268)
+++ mlc/array/3d.hh	(working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2001, 2002, 2003, 2004  EPITA Research and Development Laboratory
+// Copyright (C) 2001, 2002, 2003, 2004, 2005  EPITA Research and Development Laboratory
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -31,9 +31,11 @@
 # include <mlc/array/objs.hh>
 # include <mlc/contract.hh>
 # include <mlc/arith.hh>
-# include <ntg/basics.hh>
+# include <mlc/ftraits.hh>
+# include <mlc/to_string.hh>
 
 # include <iostream>
+# include <cmath>
 
 // impl
 # include <mlc/array/3d.hxx>
@@ -41,6 +43,19 @@
 namespace mlc
 {
 
+  // fwd decl
+  template<class Info_, class T_>
+  struct array3d;
+
+  // binary traits
+  template <class Tag, class Info_, class T_, class U>
+  struct binary_traits <Tag, array3d<Info_, T_>, U>
+  {
+    typedef typename binary_traits<Tag, T_, U>::ret V;
+    typedef array3d<Info_, V> ret;
+  };
+
+
   class not_implemented_yet{}; // FIXME
 
   template<class Info_, class T_>
@@ -88,7 +103,7 @@
     static std::string
     name()
     {
-      return std::string("array3d< Info, ") + ntg_name(T) + " >";
+      return std::string("array3d< Info, ") + mlc_to_string(T) + " >";
     }
 
 
@@ -99,12 +114,12 @@
 
     // Normalize (absolute values -> relative values)
 
-    array3d<Info_, ntg::float_s>
+    array3d<Info_, float>
     normalize()
     {
-      array3d<Info_, ntg::float_s> tmp;
-      ntg::float_s sum = 0.f;
-      const ntg::float_s epsilon = 0.01f; // FIXME : epsilon should be global
+      array3d<Info_, float> tmp;
+      float sum = 0.f;
+      const float epsilon = 0.01f; // FIXME : epsilon should be global
       unsigned i;
       for (i = 0; i < Info_::card; ++i)
 	sum += this->buffer_[i];
@@ -114,7 +129,7 @@
       sum = 0.f;
       for (i = 0; i < Info_::card; ++i)
 	sum += tmp[i];
-      postcondition(std::abs(sum - 1) <= epsilon);
+      postcondition(std::fabs(sum - 1) <= epsilon);
       return tmp;
     }
 
@@ -151,20 +166,20 @@
     // Think of a mechanism similar to apply() and apply2().
 
     template <class U>
-    array3d< Info, ntg_return_type(times, T, U) >
+    array3d< Info, mlc_binary_ret(times, T, U) >
     operator*(U w)
     {
-      array3d< Info, ntg_return_type(times, T, U) > tmp;
+      array3d< Info, mlc_binary_ret(times, T, U) > tmp;
       for (unsigned i = 0; i < Info::card; ++i)
 	tmp[i] = this->buffer_[i] * w;
       return tmp;
     }
 
     template <class U>
-    array3d< Info, ntg_return_type(div, T, U) >
+    array3d< Info, mlc_binary_ret(div, T, U) >
     operator/(U w)
     {
-      array3d< Info, ntg_return_type(div, T, U) > tmp;
+      array3d< Info, mlc_binary_ret(div, T, U) > tmp;
       for (unsigned i = 0; i < Info::card; ++i)
 	tmp[i] = this->buffer_[i] / w;
       return tmp;
