diff --git a/Changelog b/Changelog
index bad19ae33373814899a64110da3d758235cedaa3..032638655591d1acf520615275efbd6427fa30fb 100644
--- a/Changelog
+++ b/Changelog
@@ -18,6 +18,7 @@
 Open Source Release <next-release>
 ###############################################################################
 
+o!  Kernel    [2024-10-08] introduce logic type Lboolean and constants
 -   Kernel    [2024-10-08] Asm contracts can now have \initialized ensures.
               See option -asm-contracts-ensure-init
 -   Kernel    [2024-10-08] Option for converting stmt contracts into
diff --git a/src/kernel_internals/parsing/logic_parser.mly b/src/kernel_internals/parsing/logic_parser.mly
index 01d7509c06f6d75a7962b12a604c1143980ea032..0f6962782bb6c79f9826c286a8854241a31b69a8 100644
--- a/src/kernel_internals/parsing/logic_parser.mly
+++ b/src/kernel_internals/parsing/logic_parser.mly
@@ -872,7 +872,7 @@ tabs:
 type_spec(tname):
 | INTEGER        { LTinteger }
 | REAL           { LTreal }
-| BOOLEAN        { LTnamed (Utf8_logic.boolean,[]) }
+| BOOLEAN        { LTboolean }
 | VOID           { LTvoid }
 | BOOL           { LTint IBool }
 | CHAR           { LTint IChar }       /** [char] */
diff --git a/src/kernel_internals/typing/logic_builtin.ml b/src/kernel_internals/typing/logic_builtin.ml
index bf6365d482160ef3b8c0a7e327339f2f1f251cd5..6ca4bb04ff2e040ada195bd7831da60332a784f7 100644
--- a/src/kernel_internals/typing/logic_builtin.ml
+++ b/src/kernel_internals/typing/logic_builtin.ml
@@ -53,9 +53,6 @@ let init =
         (*
           let tvar v = new_identified_term (tvar v) in
          *)
-        let boolean =
-          { lt_name=Utf8_logic.boolean; lt_params=[]; lt_def=None; lt_attr=[] }
-        in
         let set =
           { lt_name = "set"; lt_params=["elem"]; lt_def=None; lt_attr=[] }
         in
@@ -72,7 +69,7 @@ let init =
           {lt_name = "rounding_mode"; lt_params = []; lt_def = None; lt_attr=[]}
         in
         List.iter (fun x -> Logic_env.add_builtin_logic_type x.lt_name x)
-          [ boolean; set; typetag; sign; float_format; rounding_mode ];
+          [ set; typetag; sign; float_format; rounding_mode ];
         (* constructors *)
         List.iter
           (fun (typename, constrs) ->
@@ -88,15 +85,13 @@ let init =
                  constrs
              in
              typename.lt_def <- Some (LTsum l))
-          [ boolean, ["\\true"; "\\false"];
-            sign , [ "\\Positive"; "\\Negative"] ;
+          [ sign , [ "\\Positive"; "\\Negative"] ;
             float_format, [ "\\Single"; "\\Double"; "\\Quad" ] ;
             rounding_mode, [ "\\Up"; "\\Down"; "\\ToZero"; "\\NearestAway";
                              "\\NearestEven" ];
           ];
         (* logic types used by the builtins *)
         let a_name, a_type = polymorphic_type "a" in
-        let boolean = Ltype(boolean,[]) in
         let sign = Ltype(sign,[]) in
         let float_format = Ltype(float_format,[]) in
         let rounding_mode = Ltype(rounding_mode,[]) in
@@ -255,7 +250,7 @@ let init =
                           "f",(Larrow ([Linteger],Lreal))], Lreal ;
             "\\numof", [], ["min",Linteger;
                             "max", Linteger;
-                            "f",(Larrow ([Linteger],boolean))], Linteger ;
+                            "f",(Larrow ([Linteger],Lboolean))], Linteger ;
 
 
             (* for floats special values *)
diff --git a/src/kernel_internals/typing/mergecil.ml b/src/kernel_internals/typing/mergecil.ml
index 73e7cc4ab67e78b6eb11eea45262069a2b113aae..d9ef2e8af3dbe3d4647d98a37ef8194e996c5508 100644
--- a/src/kernel_internals/typing/mergecil.ml
+++ b/src/kernel_internals/typing/mergecil.ml
@@ -1834,7 +1834,7 @@ let pp_profiles fmt li =
 
 let logic_info_of_logic_var lv =
   let rec extract_tparams tparams = function
-    | Ctype _ | Linteger | Lreal -> tparams
+    | Ctype _ | Linteger | Lreal | Lboolean -> tparams
     | Ltype (_,l) -> List.fold_left extract_tparams tparams l
     | Lvar s -> Datatype.String.Set.add s tparams
     | Larrow (l,t) ->
diff --git a/src/kernel_services/ast_data/cil_types.ml b/src/kernel_services/ast_data/cil_types.ml
index 3c0114a58533f3b45b7a984e8b074a9ac779c6e0..9f8f661f037cec928cc29ad8791e4cc0f7bebf63 100644
--- a/src/kernel_services/ast_data/cil_types.ml
+++ b/src/kernel_services/ast_data/cil_types.ml
@@ -1334,6 +1334,7 @@ and location = Filepath.position * Filepath.position
 (** {1 Abstract syntax trees for annotations} *)
 
 and logic_constant =
+  | Boolean of bool
   | Integer of Integer.t * string option
   (** Integer constant with a textual representation.  *)
   | LStr of string (** String constant. *)
@@ -1356,6 +1357,7 @@ and logic_type =
   | Ltype of logic_type_info * logic_type list
   (** an user-defined logic type with its parameters *)
   | Lvar of string (** a type variable. *)
+  | Lboolean (** booleans *)
   | Linteger (** mathematical integers, {i i.e.} Z *)
   | Lreal    (** mathematical reals, {i i.e.} R *)
   | Larrow of logic_type list * logic_type (** (n-ary) function type *)
diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml
index fc7d05c72804a2d36f0dbf0c858ef8de51dd3097..c018fc00b8bbc864177b46e20ed6d725d8bef91c 100644
--- a/src/kernel_services/ast_printing/cil_printer.ml
+++ b/src/kernel_services/ast_printing/cil_printer.ml
@@ -2358,6 +2358,8 @@ class cil_printer () = object (self)
     (* ******************************************************************* *)
 
   method logic_constant fmt = function
+    | Boolean true -> self#pp_acsl_keyword fmt "\\true"
+    | Boolean false -> self#pp_acsl_keyword fmt "\\false"
     | Integer(_, Some s) when print_as_source s ->
       fprintf fmt "%s" s (* Always print the text if there is one, unless
                             we want to print it as hexa *)
@@ -2389,6 +2391,11 @@ class cil_printer () = object (self)
     in
     function
     | Ctype typ -> self#typ name fmt typ
+    | Lboolean ->
+      let res =
+        if Kernel.Unicode.get () then Utf8_logic.boolean else "boolean"
+      in
+      Format.fprintf fmt "%s%t" res pname
     | Linteger ->
       let res =
         if Kernel.Unicode.get () then Utf8_logic.integer else "integer"
@@ -2399,11 +2406,6 @@ class cil_printer () = object (self)
         if Kernel.Unicode.get () then Utf8_logic.real else "real"
       in
       Format.fprintf fmt "%s%t" res pname
-    | Ltype ({ lt_name = name},[]) when name = Utf8_logic.boolean ->
-      let res =
-        if Kernel.Unicode.get () then Utf8_logic.boolean else "boolean"
-      in
-      Format.fprintf fmt "%s%t" res pname
     | Ltype (s,l) ->
       fprintf fmt "%a%a%t" self#logic_type_info s
         ((* the space avoids the issue of list<list<int>> where the double >
diff --git a/src/kernel_services/ast_printing/cil_types_debug.ml b/src/kernel_services/ast_printing/cil_types_debug.ml
index 4a1ae03abc0409845ad9d794b96efe4fc24b9f85..42fa14470042a00252b7a68dcb34e978d891cb62 100644
--- a/src/kernel_services/ast_printing/cil_types_debug.ml
+++ b/src/kernel_services/ast_printing/cil_types_debug.ml
@@ -596,6 +596,8 @@ and pp_if_loc_known prefix suffix fmt loc =
   else ()
 
 and pp_logic_constant fmt = function
+  | Boolean b ->
+    Format.fprintf fmt "Boolean(%B)" b
   | Integer(integer,string_option) ->
     Format.fprintf fmt "Integer(%a,%a)"  pp_integer integer  (pp_option pp_string) string_option
   | LStr(string) -> Format.fprintf fmt "LStr(%a)"  pp_string string
@@ -616,6 +618,7 @@ and pp_logic_type fmt = function
   | Ltype(logic_type_info,logic_type_list) ->
     Format.fprintf fmt "Ltype(%a,%a)"  pp_logic_type_info logic_type_info  (pp_list pp_logic_type) logic_type_list
   | Lvar(string) -> Format.fprintf fmt "Lvar(%a)"  pp_string string
+  | Lboolean -> Format.fprintf fmt "Lboolean"
   | Linteger -> Format.fprintf fmt "Linteger"
   | Lreal -> Format.fprintf fmt "Lreal"
   | Larrow(logic_type_list,logic_type) ->
diff --git a/src/kernel_services/ast_printing/logic_print.ml b/src/kernel_services/ast_printing/logic_print.ml
index 91bbf80e966b1defd19735cf112733140c021122..0c27e9c2ffd78fe1342086291d75fa66b6dc50d5 100644
--- a/src/kernel_services/ast_printing/logic_print.ml
+++ b/src/kernel_services/ast_printing/logic_print.ml
@@ -49,6 +49,10 @@ let rec print_logic_type name fmt typ =
     in
     print_logic_type (Some pname) fmt t
   | LTvoid -> fprintf fmt "void%t" pname
+  | LTboolean ->
+    fprintf fmt "%s%t"
+      (if Kernel.Unicode.get () then Utf8_logic.boolean else "boolean")
+      pname
   | LTinteger ->
     fprintf fmt "%s%t"
       (if Kernel.Unicode.get () then Utf8_logic.integer else "integer")
diff --git a/src/kernel_services/ast_queries/ast_diff.ml b/src/kernel_services/ast_queries/ast_diff.ml
index d82c70ccfe7300dc85d897a1f3f695b63b77c876..2b92a40cc21072e33bb363188d14f88d90620172 100644
--- a/src/kernel_services/ast_queries/ast_diff.ml
+++ b/src/kernel_services/ast_queries/ast_diff.ml
@@ -545,7 +545,7 @@ and is_same_logic_constant c c' env =
      | `Same ei'' -> Cil_datatype.Enumitem.equal ei' ei''
      | `Not_present -> false)
   | LEnum _, _ | _, LEnum _ -> false
-  | (Integer _ | LStr _ | LWStr _ | LChr _ | LReal _), _ ->
+  | (Boolean _ | Integer _ | LStr _ | LWStr _ | LChr _ | LReal _), _ ->
     Cil_datatype.Logic_constant.equal c c'
 
 and is_same_term t t' env =
@@ -763,12 +763,14 @@ and is_same_logic_type t t' env =
     is_matching_logic_type_info t t' env &&
     is_same_list is_same_logic_type prms prms' env
   | Lvar s, Lvar s' -> is_matching_logic_type_var s s' env
+  | Lboolean, Lboolean -> true
   | Linteger, Linteger -> true
   | Lreal, Lreal -> true
   | Larrow(args,rt), Larrow(args', rt')  ->
     is_same_list is_same_logic_type args args' env &&
     is_same_logic_type rt rt' env
-  | (Ctype _ | Ltype _ | Lvar _ | Linteger | Lreal | Larrow _),_ -> false
+  | (Ctype _ | Ltype _ | Lvar _ | Linteger | Lboolean | Lreal | Larrow _),_ ->
+    false
 
 and is_same_inductive_case (_,labs,tprms,p) (_,labs',tprms',p') env =
   let res, env =
diff --git a/src/kernel_services/ast_queries/ast_info.ml b/src/kernel_services/ast_queries/ast_info.ml
index c9bbec26a5ed4b8928e81fd5983d43aec41f70d3..4a175d3957548c18a985bf514fb8e6aa75c12a3c 100644
--- a/src/kernel_services/ast_queries/ast_info.ml
+++ b/src/kernel_services/ast_queries/ast_info.ml
@@ -75,7 +75,7 @@ let is_non_null_expr e =
 
 let is_integral_logic_const = function
   | Integer _ | LEnum _ | LChr _ -> true
-  | LStr _ | LWStr _ | LReal _ -> false
+  | LStr _ | LWStr _ | LReal _ | Boolean _ -> false
 
 let possible_value_of_integral_logic_const = function
   | Integer(i,_) -> Some i
diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml
index f67e99e886011622d09f9db98c0e3b4b27d0bc69..d0ae997cb8a69a18b72a22113e9c7577ecd8353a 100644
--- a/src/kernel_services/ast_queries/cil.ml
+++ b/src/kernel_services/ast_queries/cil.ml
@@ -1508,7 +1508,7 @@ and childrenLogicType vis ty =
     Ctype t ->
     let t' = visitCilType vis t in
     if t != t' then Ctype t' else ty
-  | Linteger | Lreal -> ty
+  | Lboolean | Linteger | Lreal -> ty
   | Ltype (s,l) ->
     let s' = doVisitCil vis (Visitor_behavior.Get.logic_type_info vis#behavior)
         vis#vlogic_type_info_use alphabetabeta s in
@@ -3276,9 +3276,8 @@ let isIntegralOrPointerType t =
 let rec isLogicBooleanType t =
   match t with
   | Ctype ty -> isIntegralType ty
-  | Linteger -> true
-  | Ltype ({lt_name = name} as tdef,_) ->
-    name = Utf8_logic.boolean ||
+  | Lboolean | Linteger -> true
+  | Ltype (tdef,_) ->
     ( is_unrollable_ltdef tdef && isLogicBooleanType (unroll_ltdef t))
   | Lreal | Lvar _ | Larrow _ -> false
 
@@ -3289,14 +3288,15 @@ let isBoolType typ = match unrollType typ with
 let rec isLogicPureBooleanType t =
   match t with
   | Ctype t -> isBoolType t
-  | Ltype ({lt_name = name} as def,_) ->
-    name = Utf8_logic.boolean ||
+  | Lboolean -> true
+  | Ltype (def,_) ->
     (is_unrollable_ltdef def && isLogicPureBooleanType (unroll_ltdef t))
   | _ -> false
 
 let rec isLogicIntegralType t =
   match t with
   | Ctype t -> isIntegralType t
+  | Lboolean -> false
   | Linteger -> true
   | Lreal -> false
   | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef ->
@@ -3311,6 +3311,7 @@ let isFloatingType t =
 let isLogicFloatType t =
   match t with
   | Ctype t -> isFloatingType t
+  | Lboolean -> false
   | Linteger -> false
   | Lreal -> false
   | Lvar _ | Ltype _ | Larrow _ -> false
@@ -3318,6 +3319,7 @@ let isLogicFloatType t =
 let rec isLogicRealOrFloatType t =
   match t with
   | Ctype t -> isFloatingType t
+  | Lboolean -> false
   | Linteger -> false
   | Lreal -> true
   | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef ->
@@ -3327,6 +3329,7 @@ let rec isLogicRealOrFloatType t =
 let rec isLogicRealType t =
   match t with
   | Ctype _ -> false
+  | Lboolean -> false
   | Linteger -> false
   | Lreal -> true
   | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef ->
@@ -3350,7 +3353,7 @@ let rec isLogicArithmeticType t =
   | Linteger | Lreal -> true
   | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef ->
     isLogicArithmeticType (unroll_ltdef ty)
-  | Lvar _ | Ltype _ | Larrow _ -> false
+  | Lboolean | Lvar _ | Ltype _ | Larrow _ -> false
 
 let isFunctionType t =
   match unrollTypeSkel t with
@@ -3541,7 +3544,7 @@ let rec typeOfTermLval = function
               Kernel.fatal ~current:true
                 "typeOfTermLval: Mem on a non-pointer"
           end
-        | Linteger | Lreal ->
+        | Lboolean | Linteger | Lreal ->
           Kernel.fatal ~current:true "typeOfTermLval: Mem on a logic type"
         | Ltype (s,_) as ty when is_unrollable_ltdef s ->
           type_of_pointed (unroll_ltdef ty)
@@ -3565,7 +3568,7 @@ and typeTermOffset basetyp =
     let rec putAttributes = function
       | Ctype typ ->
         Ctype (typeAddAttributes contagious typ)
-      | Linteger | Lreal ->
+      | Lboolean | Linteger | Lreal ->
         Kernel.fatal ~current:true
           "typeTermOffset: Attribute on a logic type"
       | Ltype (s,_) as ty when is_unrollable_ltdef s ->
@@ -3596,7 +3599,8 @@ and typeTermOffset basetyp =
               Kernel.fatal ~current:true
                 "typeTermOffset: Index on a non-array"
           end
-        | Linteger | Lreal -> Kernel.fatal ~current:true "typeTermOffset: Index on a logic type"
+        | Lboolean | Linteger | Lreal ->
+          Kernel.fatal ~current:true "typeTermOffset: Index on a logic type"
         | Ltype (s,_) as ty when is_unrollable_ltdef s ->
           elt_type (unroll_ltdef ty)
         | Ltype (s,_) ->
@@ -3617,7 +3621,8 @@ and typeTermOffset basetyp =
             blendAttributes baseAttrs fieldType
           | _ ->  Kernel.fatal ~current:true "typeTermOffset: Field on a non-compound"
         end
-      | Linteger | Lreal -> Kernel.fatal ~current:true "typeTermOffset: Field on a logic type"
+      | Lboolean | Linteger | Lreal ->
+        Kernel.fatal ~current:true "typeTermOffset: Field on a logic type"
       | Ltype (s,_) as ty when is_unrollable_ltdef s ->
         elt_type (unroll_ltdef ty)
       | Ltype (s,_) ->
@@ -3640,7 +3645,7 @@ let isVolatileType typ_lval = typeHasAttributeMemoryBlock "volatile" typ_lval
 
 let rec isVolatileLogicType = function
   | Ctype typ -> isVolatileType typ
-  | Linteger | Lreal | Lvar _ | Larrow _ -> false
+  | Lboolean | Linteger | Lreal | Lvar _ | Larrow _ -> false
   | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef ->
     isVolatileLogicType (unroll_ltdef ty)
   | Ltype _ -> false
diff --git a/src/kernel_services/ast_queries/cil_const.ml b/src/kernel_services/ast_queries/cil_const.ml
index 20033aed2b0d8163ee290341ce9999f11a086dab..019ba5281b355651fc34a1e369254b592f68b9c1 100644
--- a/src/kernel_services/ast_queries/cil_const.ml
+++ b/src/kernel_services/ast_queries/cil_const.ml
@@ -47,6 +47,7 @@ open Cil_types
 (* Types *)
 
 let voidType = TVoid([])
+let boolType = TInt(IBool,[])
 let intType = TInt(IInt,[])
 let uintType = TInt(IUInt,[])
 let shortType = TInt(IShort, [])
@@ -192,4 +193,3 @@ let make_logic_type name = {
   lt_def = None ;
   lt_attr = [] ;
 }
-
diff --git a/src/kernel_services/ast_queries/cil_const.mli b/src/kernel_services/ast_queries/cil_const.mli
index 1c3c1cf27bacc1952bc76db8f87a4b71cdede787..e08071f1b3c93e67fdb8562ac0e3c1615d1d4641 100644
--- a/src/kernel_services/ast_queries/cil_const.mli
+++ b/src/kernel_services/ast_queries/cil_const.mli
@@ -48,6 +48,10 @@ open Cil_types
 (** void *)
 val voidType: typ
 
+(** bool
+    @since Frama-C+dev *)
+val boolType: typ
+
 (** int
     @since Frama-C+dev *)
 val intType: typ
diff --git a/src/kernel_services/ast_queries/cil_datatype.ml b/src/kernel_services/ast_queries/cil_datatype.ml
index 4ab4e41617b53d0a053fc0ce373f21f436e2449e..65c8fe4fdb064a6164a459542b3b91f0267d9f5b 100644
--- a/src/kernel_services/ast_queries/cil_datatype.ml
+++ b/src/kernel_services/ast_queries/cil_datatype.ml
@@ -1405,12 +1405,13 @@ end
 
 let rec compare_logic_type config v1 v2 =
   let rank = function
-    | Linteger -> 0
-    | Lreal -> 1
-    | Ctype _ -> 2
-    | Lvar _ -> 3
-    | Ltype _ -> 4
-    | Larrow _ -> 5
+    | Lboolean -> 0
+    | Linteger -> 1
+    | Lreal -> 2
+    | Ctype _ -> 3
+    | Lvar _ -> 4
+    | Ltype _ -> 5
+    | Larrow _ -> 6
   in
   let v1 = if config.unroll then !punrollLogicType v1 else v1 in
   let v2 = if config.unroll then !punrollLogicType v2 else v2 in
@@ -1426,6 +1427,7 @@ let rec compare_logic_type config v1 v2 =
       if c <> 0 then c
       else compare_list (compare_logic_type config) ts1 ts2
     | Lvar x1, Lvar x2 -> Datatype.String.compare x1 x2
+    | Lboolean, Lboolean -> 0
     | Linteger, Linteger -> 0
     | Lreal, Lreal -> 0
     | Larrow(l1, t1), Larrow(l2, t2) ->
@@ -1434,8 +1436,9 @@ let rec compare_logic_type config v1 v2 =
     | _ -> assert false
 
 let rec hash_logic_type config = function
-  | Linteger -> 0
-  | Lreal -> 1
+  | Lboolean -> 0
+  | Linteger -> 1
+  | Lreal -> 2
   | Ctype ty -> hash_type config ty
   | Ltype({ lt_def = Some (LTsyn t)},_) when config.unroll ->
     hash_logic_type config t
@@ -1593,19 +1596,21 @@ let compare_logic_real r1 r2 =
         String.compare r1.r_literal r2.r_literal
 
 let compare_logic_constant c1 c2 = match c1,c2 with
+  | Boolean b1, Boolean b2 -> compare b1 b2
   | Integer (i1,_), Integer(i2,_) -> Integer.compare i1 i2
   | LStr s1, LStr s2 -> Datatype.String.compare s1 s2
   | LWStr s1, LWStr s2 -> compare_list Datatype.Int64.compare s1 s2
   | LChr c1, LChr c2 -> Datatype.Char.compare c1 c2
   | LReal r1, LReal r2 -> compare_logic_real r1 r2
   | LEnum e1, LEnum e2 -> Enumitem.compare e1 e2
+  | Boolean _,(Integer _ | LStr _|LWStr _ |LChr _|LReal _|LEnum _) -> 1
   | Integer _,(LStr _|LWStr _ |LChr _|LReal _|LEnum _) -> 1
   | LStr _ ,(LWStr _ |LChr _|LReal _|LEnum _) -> 1
   | LWStr _ ,(LChr _|LReal _|LEnum _) -> 1
   | LChr _,(LReal _|LEnum _) -> 1
   | LReal _,LEnum _ -> 1
-  | (LStr _|LWStr _ |LChr _|LReal _|LEnum _),
-    (Integer _|LStr _|LWStr _ |LChr _|LReal _) -> -1
+  | (Integer _ |LStr _|LWStr _ |LChr _|LReal _|LEnum _),
+    (Boolean _ |Integer _|LStr _|LWStr _ |LChr _|LReal _) -> -1
 
 let rec compare_term t1 t2 =
   let r1 = rank_term t1.term_node in
@@ -1813,6 +1818,7 @@ let hash_logic_constant = function
   | LStr s -> Datatype.String.hash s
   | LWStr l -> hash_list Datatype.Int64.hash l
   | LChr c  -> Datatype.Char.hash c
+  | Boolean b -> Datatype.Bool.hash b
   | Integer(n, _) -> Integer.hash n
   | LReal r ->
     if is_exact_float r then Datatype.Float.hash r.r_lower
diff --git a/src/kernel_services/ast_queries/logic_const.ml b/src/kernel_services/ast_queries/logic_const.ml
index 91f440b76c33bc75741e383ad78c2e3e3e5b25ce..8452b091dd8aabc50fdee5e26a46b88c73891b47 100644
--- a/src/kernel_services/ast_queries/logic_const.ml
+++ b/src/kernel_services/ast_queries/logic_const.ml
@@ -149,7 +149,7 @@ let rec instantiate subst = function
     (* This is an application of type parameters:
        no need to recursively substitute in the resulting type. *)
     (try List.assoc v subst with Not_found -> ty)
-  | Ctype _ | Linteger | Lreal as ty -> ty
+  | Ctype _ | Linteger | Lreal | Lboolean as ty -> ty
 
 let is_unrollable_ltdef = function
   | {lt_def=Some (LTsyn _)} -> true
@@ -166,12 +166,12 @@ let rec unroll_ltdef = function
     unroll_ltdef (instantiate subst ty)
   | Ltype ({lt_def= None},_)
   | Ltype ({lt_def= Some (LTsum _)},_)
-  | Linteger | Lreal | Lvar _ | Larrow _ | Ctype _ as ty  -> ty
+  | Linteger | Lboolean | Lreal | Lvar _ | Larrow _ | Ctype _ as ty  -> ty
 
 let rec isLogicCType f = function
   | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef ->
     isLogicCType f (unroll_ltdef ty)
-  | Ltype _ | Linteger | Lreal | Lvar _ | Larrow _ -> false
+  | Ltype _ | Linteger | Lboolean | Lreal | Lvar _ | Larrow _ -> false
   | Ctype cty  -> f cty
 
 let rec is_list_type = function
@@ -238,13 +238,11 @@ let make_arrow_type args rt =
   | _ -> Larrow(List.map (fun x -> x.lv_type) args, rt)
 
 let rec is_boolean_type = function
-  | Ltype ({ lt_name = s }, []) when s = Utf8_logic.boolean -> true
+  | Lboolean -> true
   | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef ->
     is_boolean_type (unroll_ltdef ty)
   | _ -> false
 
-let boolean_type = Ltype ({ lt_name = Utf8_logic.boolean ; lt_params = [] ; lt_def = None; lt_attr = [] } , [])
-
 (** {2 Offsets} *)
 
 let rec lastTermOffset (off: term_offset) : term_offset =
@@ -279,6 +277,9 @@ let trange ?(loc=Cil_datatype.Location.unknown) (low,high) =
   term ~loc (Trange(low,high))
     (Ltype(Logic_env.find_logic_type "set",[Linteger]))
 
+let tboolean ?(loc=Cil_datatype.Location.unknown) b =
+  term ~loc (TConst (Boolean b)) Lboolean
+
 (** An integer constant (of type integer). *)
 let tinteger ?(loc=Cil_datatype.Location.unknown) i =
   term ~loc (TConst (Integer (Integer.of_int i,None))) Linteger
diff --git a/src/kernel_services/ast_queries/logic_const.mli b/src/kernel_services/ast_queries/logic_const.mli
index bf69aa11aca30c3702f2d35c3b6154f7ade35f01..d5b6b3e495976d6eefd085fa85a3d83d4d9fe358 100644
--- a/src/kernel_services/ast_queries/logic_const.mli
+++ b/src/kernel_services/ast_queries/logic_const.mli
@@ -289,9 +289,6 @@ val make_arrow_type: logic_var list -> logic_type -> logic_type
 (** @return true if the argument is the boolean type. *)
 val is_boolean_type: logic_type -> bool
 
-(** @since Sodium-20150201 *)
-val boolean_type: logic_type
-
 (* ************************************************************************** *)
 (** {1 Logic Terms} *)
 (* ************************************************************************** *)
@@ -302,6 +299,11 @@ val term : ?loc:Location.t -> term_node -> logic_type -> term
 (** [..] of integers *)
 val trange: ?loc:Location.t -> term option * term option -> term
 
+(** boolean constant
+    @since Frama-C+dev
+*)
+val tboolean: ?loc:Location.t -> bool -> term
+
 (** integer constant *)
 val tinteger: ?loc:Location.t -> int -> term
 
diff --git a/src/kernel_services/ast_queries/logic_to_c.ml b/src/kernel_services/ast_queries/logic_to_c.ml
index 3fe95d67f7c3f97bb231f1d5e141f2b12c38ed8b..e2ceb635f678a35241acdc7fce0820ce3b8deb69 100644
--- a/src/kernel_services/ast_queries/logic_to_c.ml
+++ b/src/kernel_services/ast_queries/logic_to_c.ml
@@ -32,8 +32,7 @@ let rec logic_type_to_typ = function
   | Linteger -> TInt(ILongLong,[]) (*TODO: to have an unlimited integer type
                                      in the logic interpretation*)
   | Lreal -> TFloat(FDouble,[]) (* TODO: handle reals, not floats... *)
-  | Ltype({lt_name = name},[]) when name = Utf8_logic.boolean  ->
-    TInt(ILongLong,[])
+  | Lboolean  -> TInt(ILongLong,[])
   | Ltype({lt_name = "set"},[t]) -> logic_type_to_typ t
   | Ltype _ | Lvar _ | Larrow _ -> error_lval ()
 
diff --git a/src/kernel_services/ast_queries/logic_typing.ml b/src/kernel_services/ast_queries/logic_typing.ml
index 69cb0cb35c6ff584a0287e04eea2b79cdf7a8f68..7fb43878542d6eb4ecb59bb9537e98ae92e31cf1 100644
--- a/src/kernel_services/ast_queries/logic_typing.ml
+++ b/src/kernel_services/ast_queries/logic_typing.ml
@@ -1014,7 +1014,7 @@ struct
     | Ctype t -> t
     | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef ->
       c_type_of loc (unroll_ltdef ty)
-    | Ltype _ | Linteger | Lreal | Lvar _ | Larrow _ ->
+    | Ltype _ | Lboolean | Linteger | Lreal | Lvar _ | Larrow _ ->
       C.error loc "not a C type"
 
   let parseInt loc s =
@@ -1136,6 +1136,7 @@ struct
         | None -> ctxt.error loc "no such type %s" id
       end
 
+    | LTboolean -> Lboolean
     | LTinteger -> Linteger
     | LTreal -> Lreal
     | LTattribute (ty,attr) ->
@@ -1413,15 +1414,16 @@ struct
       with
       | Ctype oldt, Ctype newt ->
         c_mk_cast ~force e oldt newt
-      | t1, Ltype ({lt_name = name},[])
-        when name = Utf8_logic.boolean && is_integral_type t1 ->
-        let t2 = Ltype (Logic_env.find_logic_type Utf8_logic.boolean,[]) in
+      | t1, Lboolean when is_integral_type t1 ->
         let e = mk_cast e Linteger in
-        Logic_const.term ~loc (TBinOp(Ne,e,lzero ~loc())) t2
-      | t1, Linteger when Logic_const.is_boolean_type t1 && explicit ->
+        Logic_const.term ~loc (TBinOp(Ne,e,lzero ~loc())) Lboolean
+      | Lboolean, Linteger when explicit ->
         logic_coerce Linteger e
-      | t1, Ctype t2 when Logic_const.is_boolean_type t1
-                       && is_integral_type newt && explicit ->
+      | Lboolean, (Linteger|Lreal) ->
+        C.error loc "invalid implicit cast from %a to %a"
+          Cil_printer.pp_logic_type e.term_type
+          Cil_printer.pp_logic_type newt
+      | Lboolean, Ctype t2 when is_integral_type newt && explicit ->
         Logic_const.term ~loc (TCast (false, Ctype t2,e)) newt
       | ty1, Ltype({lt_name="set"},[ty2])
         when is_pointer_type ty1 &&
@@ -1438,14 +1440,14 @@ struct
       | _ , Ltype({lt_name =  "set"},[ ty2 ]) ->
         let e = mk_cast e ty2 in
         logic_coerce (make_set_type e.term_type) e
-      | Linteger, Linteger | Lreal, Lreal -> e
+      | Lboolean, Lboolean | Linteger, Linteger | Lreal, Lreal -> e
       | Linteger, Ctype t when isLogicPointerType newt && isLogicNull e ->
         c_mk_cast ~force e Cil_const.intType t
       | Linteger, (Ctype newt) | Lreal, (Ctype newt) when explicit ->
         Logic_utils.mk_cast ~loc newt e
       | Linteger, Ctype t when isIntegralType t ->
         (try C.integral_cast t e with Failure s -> C.error loc "%s" s)
-      | Linteger, Ctype _ | Lreal, Ctype _ ->
+      | Linteger, Ctype _ | Lreal, Ctype _ | Lboolean, Ctype _ ->
         C.error loc "invalid implicit cast from %a to C type %a"
           Cil_printer.pp_logic_type e.term_type
           Cil_printer.pp_logic_type newt
@@ -1454,7 +1456,7 @@ struct
         Logic_const.term
           ~loc (Tapp(truncate_info,[], [logic_coerce Lreal e])) Linteger
       | Ctype t, Lreal when isArithmeticType t -> logic_coerce Lreal e
-      | Ctype _, (Lreal | Linteger) ->
+      | Ctype _, (Lreal | Linteger | Lboolean) ->
         C.error loc "invalid implicit cast from %a to logic type %a"
           Cil_printer.pp_logic_type e.term_type
           Cil_printer.pp_logic_type newt
@@ -1466,6 +1468,10 @@ struct
         C.error loc
           "invalid cast from real to integer. \
            Use conversion functions instead"
+      | (Linteger | Lreal), Lboolean ->
+        C.error loc
+          "invalid cast arithmetic logic type to boolean. \
+           Use conversion functions instead"
       | Larrow (args1,_), Larrow(args2,rt2) ->
         (match e.term_node with
          | Tlambda (prms,body) when
@@ -1561,6 +1567,7 @@ struct
       else
         C.error loc "invalid implicit conversion from '%a' to '%a'"
           Cil_printer.pp_typ ty1 Cil_printer.pp_typ ty2
+    | Ctype ty, Lboolean when Cil.isBoolType ty -> Lboolean, oterm
     | Ctype ty, Linteger when Cil.isIntegralType ty -> Linteger, oterm
     | Ctype ty, Lreal when Cil.isArithmeticType ty -> Lreal, oterm
     | Linteger, Lreal -> Lreal, oterm
@@ -1600,7 +1607,7 @@ struct
         else term
       in
       stype, term
-    | Linteger, Linteger | Lreal, Lreal -> ot, oterm
+    | Lboolean, Lboolean | Linteger, Linteger | Lreal, Lreal -> ot, oterm
     | Lvar s1, Lvar s2 when s1 = s2 -> ot, oterm
     | Larrow(args1,rt1), Larrow(args2,rt2)
       when List.length args1 = List.length args2 ->
@@ -1613,8 +1620,8 @@ struct
       in
       let rt,_ = implicit_conversion ~overloaded loc oterm rt1 rt2 in
       Larrow(args,rt), oterm
-    | ((Ctype _| Linteger | Lreal | Ltype _ | Lvar _ | Larrow _),
-       (Ctype _| Linteger | Lreal | Ltype _ | Lvar _ | Larrow _)) ->
+    | ((Ctype _| Lboolean | Linteger | Lreal | Ltype _ | Lvar _ | Larrow _),
+       (Ctype _| Lboolean | Linteger | Lreal | Ltype _ | Lvar _ | Larrow _)) ->
       if overloaded then raise Not_applicable
       else
         C.error loc "invalid implicit conversion from %a to %a"
@@ -1632,13 +1639,9 @@ struct
       else
         C.error loc "incompatible types %a and %a@."
           Cil_printer.pp_typ ot Cil_printer.pp_typ nt
-    | Ctype ot, (Ltype({lt_name = n},[]) as nt) when
-        n = Utf8_logic.boolean && Cil.isIntegralType ot -> nt
-    | Ltype({lt_name = n},[]) as ot, Ctype nt when
-        n = Utf8_logic.boolean && Cil.isIntegralType nt -> ot
-    | (Linteger, (Ltype({lt_name = n},[]) as t)
-      | (Ltype({lt_name = n},[]) as t), Linteger)
-      when n = Utf8_logic.boolean -> t
+    | Ctype ot, (Lboolean as nt) when Cil.isIntegralType ot -> nt
+    | Lboolean as ot, Ctype nt when Cil.isIntegralType nt -> ot
+    | (Linteger, (Lboolean as t) | (Lboolean as t), Linteger) -> t
     | Ltype(ot,oprms), Ltype(nt,nprms) when ot == nt ->
       let res =
         List.map2 (find_supertype ~overloaded loc t) oprms nprms
@@ -1659,6 +1662,7 @@ struct
     | Ctype ot, Linteger when Cil.isIntegralType ot -> Linteger
     | Ctype ot, Linteger when Cil.isPointerType ot && isLogicNull t ->
       Ctype ot
+    | Lboolean, Lboolean -> Lboolean
     | Linteger, Linteger -> Linteger
     | Linteger, Lreal -> Lreal
     | Linteger, Ctype nt when Cil.isArithmeticType nt -> Lreal
@@ -1672,7 +1676,7 @@ struct
       let ret = find_supertype ~overloaded loc t oret nret in
       let args = List.map2 (find_supertype ~overloaded loc t) nargs oargs in
       Larrow(args,ret)
-    | (Ctype _ | Ltype _ | Lvar _ | Linteger | Lreal | Larrow _), _ ->
+    | (Ctype _ | Ltype _ | Lvar _ | Lboolean | Linteger | Lreal | Larrow _), _ ->
       if overloaded then raise Not_applicable
       else
         C.error loc "incompatible types %a and %a"
@@ -1768,8 +1772,8 @@ struct
       env, make_set_type ot, make_set_type nt
     | t1,t2 when plain_boolean_type t1 && plain_boolean_type t2 ->
       env,ot,nt
-    | ((Ctype _ | Linteger | Lreal | Ltype ({lt_name = "boolean"},[])),
-       (Ctype _ | Linteger | Lreal | Ltype ({ lt_name = "boolean"},[]))) ->
+    | ((Ctype _ | Linteger | Lreal | Lboolean),
+       (Ctype _ | Linteger | Lreal | Lboolean)) ->
       env,ot,nt
     | (Ltype _|Larrow _|Lvar _), _ | _, (Larrow _| Ltype _|Lvar _) ->
       if overloaded then raise Not_applicable
@@ -1857,18 +1861,17 @@ struct
            Cil_printer.pp_logic_type t)
     | Ltype ({lt_name="set"} as lt,[t]) ->
       Ltype(lt,[logic_arithmetic_promotion t])
-    | Ltype _ | Lvar _ | Larrow _ ->
+    | Lboolean | Ltype _ | Lvar _ | Larrow _ ->
       Kernel.fatal ~current:true
         "logic arithmetic promotion on non-arithmetic type %a"
         Cil_printer.pp_logic_type t
 
   let rec integral_promotion t =
     match unroll_type t with
-    | Ctype ty when isIntegralType ty ->
-      Linteger
+    | Ctype ty when isIntegralType ty -> Linteger
     | Linteger -> Linteger
     | Ltype ({lt_name="set"} as lt,[t]) -> Ltype(lt,[integral_promotion t])
-    | Ltype _ | Lreal | Lvar _ | Larrow _ | Ctype _ ->
+    | Lboolean | Ltype _ | Lreal | Lvar _ | Larrow _ | Ctype _ ->
       Kernel.fatal ~current:true
         "logic integral promotion on non-integral type %a"
         Cil_printer.pp_logic_type t
@@ -1968,12 +1971,8 @@ struct
         when Cil.isArithmeticType t -> Lreal
       (* In ACSL, you can convert implicitely from integral to boolean =>
          prefer boolean as common type when doing comparison. *)
-      | Ltype({lt_name = name},[]), t
-        when is_integral_type t && name = Utf8_logic.boolean ->
-        Ltype(Logic_env.find_logic_type Utf8_logic.boolean,[])
-      | t, Ltype({lt_name = name},[])
-        when is_integral_type t && name = Utf8_logic.boolean ->
-        Ltype(Logic_env.find_logic_type Utf8_logic.boolean,[])
+      | Lboolean, t when is_integral_type t -> Lboolean
+      | t, Lboolean when is_integral_type t -> Lboolean
       | Lreal, Ctype ty | Ctype ty, Lreal when isArithmeticType ty -> Lreal
       | Ltype (s1,l1), Ltype (s2,l2)
         when s1.lt_name = s2.lt_name && List.for_all2 is_same_type l1 l2 ->
@@ -3083,16 +3082,11 @@ struct
     | PLrel (t1, (Eq | Neq | Lt | Le | Gt | Ge as op), t2) ->
       let env = drop_qualifiers env in
       let f _ op t1 t2 =
-        (TBinOp(binop_of_rel op, t1, t2),
-         Ltype(Logic_env.find_logic_type Utf8_logic.boolean,[]))
+        (TBinOp(binop_of_rel op, t1, t2), Lboolean)
       in
       type_relation ctxt env f t1 op t2
-    | PLtrue ->
-      let ctrue = Logic_env.find_logic_ctor "\\true" in
-      TDataCons(ctrue,[]), Ltype(ctrue.ctor_type,[])
-    | PLfalse ->
-      let cfalse = Logic_env.find_logic_ctor "\\false" in
-      TDataCons(cfalse,[]), Ltype(cfalse.ctor_type,[])
+    | PLtrue -> TConst(Boolean true), Lboolean
+    | PLfalse -> TConst(Boolean false), Lboolean
     | PLlambda(prms,e) ->
       let env = drop_qualifiers env in
       let (prms, env) = add_quantifiers ctxt loc ~kind:LVFormal prms env in
@@ -3101,17 +3095,17 @@ struct
     | PLnot t ->
       let env = drop_qualifiers env in
       let t = type_bool_term ctxt env t in
-      TUnOp(LNot,t), Ltype (Logic_env.find_logic_type Utf8_logic.boolean,[])
+      TUnOp(LNot,t), Lboolean
     | PLand (t1,t2) ->
       let env = drop_qualifiers env in
       let t1 = type_bool_term ctxt env t1 in
       let t2 = type_bool_term ctxt env t2 in
-      TBinOp(LAnd,t1,t2), Ltype (Logic_env.find_logic_type Utf8_logic.boolean,[])
+      TBinOp(LAnd,t1,t2), Lboolean
     | PLor (t1,t2) ->
       let env = drop_qualifiers env in
       let t1 = type_bool_term ctxt env t1 in
       let t2 = type_bool_term ctxt env t2 in
-      TBinOp(LOr,t1,t2), Ltype (Logic_env.find_logic_type Utf8_logic.boolean,[])
+      TBinOp(LOr,t1,t2), Lboolean
     | PLtypeof t1 ->
       let env = drop_qualifiers env in
       let t1 = term env t1 in
@@ -3119,7 +3113,7 @@ struct
     | PLtype ty ->
       begin match logic_type ctxt loc env ty with
         | Ctype ty -> Ttype ty, Ltype (Logic_env.find_logic_type "typetag",[])
-        | Linteger | Lreal | Ltype _ | Lvar _ | Larrow _ ->
+        | Lboolean | Linteger | Lreal | Ltype _ | Lvar _ | Larrow _ ->
           ctxt.error loc "cannot take type tag of logic type"
       end
     | PLlet (ident, def, body) ->
@@ -3403,7 +3397,7 @@ struct
     if not (plain_boolean_type tt.term_type) then
       ctxt.error t.lexpr_loc "boolean expected but %a found"
         Cil_printer.pp_logic_type tt.term_type;
-    mk_cast tt (Ltype (Logic_env.find_logic_type Utf8_logic.boolean,[]))
+    mk_cast tt Lboolean
 
   and type_num_term_option ctxt env t =
     match t with
diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml
index ecadf4ba6eda50471cfdcbf829e71e247f951b01..5003975902505b717b0ad3ea36bbe30e6864c4d0 100644
--- a/src/kernel_services/ast_queries/logic_utils.ml
+++ b/src/kernel_services/ast_queries/logic_utils.ml
@@ -33,7 +33,8 @@ let rec unroll_type ?(unroll_typedef=true) = function
   | Ltype (tdef,_) as ty when Logic_const.is_unrollable_ltdef tdef ->
     unroll_type ~unroll_typedef (Logic_const.unroll_ltdef ty)
   | Ctype ty when unroll_typedef -> Ctype (Cil.unrollType ty)
-  | Linteger | Lreal | Lvar _ | Larrow _ | Ctype _ | Ltype _ as ty  -> ty
+  | Linteger | Lboolean | Lreal | Lvar _ | Larrow _ | Ctype _ | Ltype _ as ty ->
+    ty
 
 let is_instance_of vars t1 t2 =
   let rec aux map t1 t2 =
@@ -56,7 +57,7 @@ let is_instance_of vars t1 t2 =
         (Cil.typeDeepDropAllAttributes t1)
         (Cil.typeDeepDropAllAttributes t2),
       map
-    | (Lvar _ | Ctype _ | Linteger | Lreal | Ltype _ | Larrow _), _ ->
+    | (Lvar _ | Ctype _ | Lboolean | Linteger | Lreal | Ltype _ | Larrow _), _ ->
       Cil_datatype.Logic_type.equal t1 t2, map
   and aux_list map l1 l2 =
     match l1, l2 with
@@ -290,6 +291,8 @@ let constant_to_lconstant c = match c with
     LReal (real_of_float s f)
 
 let lconstant_to_constant c = match c with
+  | Boolean b ->
+    CInt64 ((if b then Integer.one else Integer.zero), IBool, None)
   | Integer (i,s) ->
     begin
       try
@@ -379,8 +382,7 @@ let is_zero_comparable t =
   match unroll_type t.term_type with
   | Ctype (TInt _ | TFloat _ | TPtr _ | TArray _ | TFun _ | TEnum _) -> true
   | Ctype (TVoid _ | TNamed _ | TComp _ | TBuiltin_va_list _) -> false
-  | Linteger | Lreal -> true
-  | Ltype ({lt_name},[]) -> lt_name = Utf8_logic.boolean
+  | Linteger | Lreal | Lboolean -> true
   | Ltype _ -> false
   | Lvar _ | Larrow _ -> false
 
@@ -393,8 +395,7 @@ let scalar_term_conversion conversion t =
   let ptr_conversion t =
     conversion ~loc false t (Logic_const.term ~loc Tnull t.term_type) in
   let bool_conversion t =
-    let ctrue = Logic_env.Logic_ctor_info.find "\\true" in
-    conversion ~loc true t (term ~loc (TDataCons(ctrue,[])) boolean_type) in
+    conversion ~loc true t (Logic_const.tboolean ~loc true) in
   match unroll_type t.term_type with
   | Ctype (TInt _ | TEnum _) -> int_conversion t
   | Ctype (TFloat _) as ltyp -> real_conversion ~ltyp t
@@ -405,8 +406,7 @@ let scalar_term_conversion conversion t =
   (* decay as pointer *)
   | Linteger -> int_conversion t
   | Lreal -> real_conversion t
-  | Ltype ({lt_name = name},[]) when name = Utf8_logic.boolean ->
-    bool_conversion t
+  | Lboolean -> bool_conversion t
   | Ltype _ | Lvar _ | Larrow _
   | Ctype (TVoid _ | TNamed _ | TComp _ | TBuiltin_va_list _)
     -> Kernel.fatal
@@ -421,7 +421,7 @@ let scalar_term_to_predicate =
 let scalar_term_to_boolean =
   let conversion ~loc is_eq t1 t2 =
     let op = if is_eq then Eq else Ne in
-    term ~loc (TBinOp(op,t1,t2)) Logic_const.boolean_type
+    term ~loc (TBinOp(op,t1,t2)) Lboolean
   in
   scalar_term_conversion conversion
 
@@ -545,7 +545,7 @@ and offset_to_term_offset = function
 
 and expr_to_boolean e =
   let open Cil_types in
-  let tbool n = Logic_const.term n Logic_const.boolean_type in
+  let tbool n = Logic_const.term n Lboolean in
   let tnot t = tbool @@ TUnOp(LNot, t) in
   let tcompare op a b =
     let va = expr_to_term ~coerce:true a in
@@ -1280,6 +1280,7 @@ let rec is_same_pl_type t1 t2 =
   let open Logic_ptree in
   match t1, t2 with
   | LTvoid, LTvoid
+  | LTboolean, LTboolean
   | LTinteger, LTinteger
   | LTreal, LTreal -> true
   | LTint k1, LTint k2 ->
@@ -1315,7 +1316,7 @@ let rec is_same_pl_type t1 t2 =
     is_same_list is_same_pl_type prms1 prms2 && is_same_pl_type t1 t2
   | LTattribute(t1,attr1), LTattribute(t2,attr2) ->
     is_same_pl_type t1 t2 && attr1 = attr2
-  | (LTvoid | LTinteger | LTreal | LTint _ | LTfloat _ | LTarrow _
+  | (LTvoid | LTboolean | LTinteger | LTreal | LTint _ | LTfloat _ | LTarrow _
     | LTarray _ | LTpointer _ | LTenum _
     | LTunion _ | LTnamed _ | LTstruct _ | LTattribute _),_ ->
     false
@@ -2209,7 +2210,7 @@ let lhost_c_type thost =
       | Ctype typ -> Some typ
       | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef ->
         get (unroll_ltdef ty)
-      | Ltype _ | Lvar _ | Linteger | Lreal | Larrow _ -> None
+      | Ltype _ | Lvar _ | Lboolean | Linteger | Lreal | Larrow _ -> None
     in
     match Logic_const.plain_or_set get lty with
     | None ->
@@ -2394,6 +2395,7 @@ let rec constFoldTermToInt ?(machdep=true) (e: term) : Integer.t option =
   | TUnOp(unop, e) -> constFoldUnOpToInt ~machdep unop e
   | TConst(LChr c) -> Some (charConstToInt c)
   | TConst(LEnum {eival = v}) -> Cil.constFoldToInt ~machdep v
+  | TConst (Boolean b) -> Some (if b then Z.one else Z.zero)
   | TConst (Integer (i, _)) -> Some i
   | TConst (LReal _ | LWStr _ | LStr _) -> None
   | TSizeOf typ -> constFoldSizeOfToInt ~machdep typ
diff --git a/src/kernel_services/parsetree/logic_ptree.ml b/src/kernel_services/parsetree/logic_ptree.ml
index 2669ced475387e4835a49716b5079143ea86bcb5..c5f7c4577947da7e4f07a72187386487453a147b 100644
--- a/src/kernel_services/parsetree/logic_ptree.ml
+++ b/src/kernel_services/parsetree/logic_ptree.ml
@@ -40,6 +40,7 @@ type array_size =
 (** logic types. *)
 type logic_type =
   | LTvoid (** C void *)
+  | LTboolean (** booleans *)
   | LTinteger (** mathematical integers. *)
   | LTreal (** mathematical real. *)
   | LTint of Cil_types.ikind (** C integral type.*)
diff --git a/src/plugins/e-acsl/src/analyses/bound_variables.ml b/src/plugins/e-acsl/src/analyses/bound_variables.ml
index 2e3e91305da4f48e33281e7d1dc0e01a3ca700ba..bb6bcecb3292a6805a73831c6e2a7d50041dd700 100644
--- a/src/plugins/e-acsl/src/analyses/bound_variables.ml
+++ b/src/plugins/e-acsl/src/analyses/bound_variables.ml
@@ -222,8 +222,7 @@ end = struct
            let v =
              match v.lv_type with
              | Ctype ty when Cil.isIntegralType ty -> v
-             | Linteger -> v
-             | Ltype _ as ty when Logic_const.is_boolean_type ty -> v
+             | Linteger | Lboolean -> v
              | Ctype _ | Ltype _ | Lvar _ | Lreal | Larrow _ ->
                Error.not_yet
                  (error_msg
diff --git a/src/plugins/e-acsl/src/analyses/interval.ml b/src/plugins/e-acsl/src/analyses/interval.ml
index 05320831cb2ba5cfce57e5d7559654b5e8cb92b2..50e43208234aec8a42d76eb3c8648d1e55d50c10 100644
--- a/src/plugins/e-acsl/src/analyses/interval.ml
+++ b/src/plugins/e-acsl/src/analyses/interval.ml
@@ -349,6 +349,7 @@ let rec infer ~force ~logic_env t =
   in
   let compute t =
     match t.term_node with
+    | TConst (Boolean b) -> singleton (if b then Z.one else Z.zero)
     | TConst (Integer (n, _)) -> singleton n
     | TConst (LChr c) ->
       let n = Cil.charConstToInt c in
@@ -488,7 +489,7 @@ let rec infer ~force ~logic_env t =
                | Some (Ctype typ) ->
                  ignore ((infer ~force ~logic_env t'));
                  interv_of_typ typ;
-               | None | Some (Linteger | Lreal | Ltype _ | Lvar _ | Larrow _) ->
+               | None | Some _ ->
                  get_res (infer ~force ~logic_env t'))
             | _ -> assert false)
        | LBnone when li.l_var_info.lv_name = "\\sum" ||
@@ -585,7 +586,7 @@ and initiate_fixpoint ~logic_env li args_ival args =
       (match li.l_type with
        | Some (Ctype typ) ->
          interv_of_typ typ, PoT_term t
-       | None | Some (Linteger | Lreal | Ltype _ | Lvar _ | Larrow _) ->
+       | None | Some _ ->
          Ival (Ival.bottom), PoT_term t)
     | _ -> assert false
   in
@@ -625,11 +626,13 @@ and infer_term_host ~force ~logic_env thost =
   | TVar v ->
     (try Logic_env.find logic_env v with Not_found ->
      match v.lv_type with
+     | Lboolean -> ival Z.zero Z.one
      | Linteger -> top_ival
      | Ctype (TFloat(fk, _)) -> Float(fk, None)
      | Lreal -> Real
      | Ctype _ -> interv_of_typ (Logic_utils.logicCType v.lv_type)
-     | Ltype _ | Lvar _ | Larrow _ -> Options.fatal "unexpected logic type")
+     | Ltype _ | Lvar _ | Larrow _ ->
+       Options.fatal "unexpected logic type")
   | TResult ty ->
     interv_of_typ ty
   | TMem t ->
@@ -733,7 +736,7 @@ and infer_bound_variable ~loc ~logic_env (t1, lv, t2) =
   let i = unify (join i1 i2) in
   let t1, t2, i =
     match lv.lv_type with
-    | Ltype _ | Lvar _ | Lreal | Larrow _ ->
+    | Ltype _ | Lvar _ | Lreal | Lboolean | Larrow _ ->
       Error.not_yet "quantification over non-integer type"
     | Linteger -> t1, t2, i
     | Ctype ty ->
diff --git a/src/plugins/e-acsl/src/analyses/memory_tracking.ml b/src/plugins/e-acsl/src/analyses/memory_tracking.ml
index 8c0478348ff40a11be1f1b57d865818f56d47980..020f06719b7fd906a16549fef106de144eae7582 100644
--- a/src/plugins/e-acsl/src/analyses/memory_tracking.ml
+++ b/src/plugins/e-acsl/src/analyses/memory_tracking.ml
@@ -259,7 +259,7 @@ module rec Transfer
 
   let may_alias li = match li.l_var_info.lv_type with
     | Ctype ty -> is_ptr_or_array ty
-    | Linteger | Lreal -> false
+    | Lboolean | Linteger | Lreal -> false
     | Ltype _ -> Error.not_yet "user defined type"
     | Lvar _ -> Error.not_yet "named type"
     | Larrow _ -> Error.not_yet "functional type"
diff --git a/src/plugins/e-acsl/src/analyses/typing.ml b/src/plugins/e-acsl/src/analyses/typing.ml
index df3fa3c6b4b174cf5ed97640890c39c9cfc0260f..b1c8f8c14f13920c2e42c82cb52c68be12beaf17 100644
--- a/src/plugins/e-acsl/src/analyses/typing.ml
+++ b/src/plugins/e-acsl/src/analyses/typing.ml
@@ -111,7 +111,8 @@ let typ_of_lty = function
   | Ctype cty -> cty
   | Linteger -> Gmp_types.Z.t ()
   | Lreal -> Error.not_yet "real type"
-  | Ltype _ | Lvar _ | Larrow _ -> Options.fatal "unexpected logic type"
+  | Lboolean | Ltype _ | Lvar _ | Larrow _ ->
+    Options.fatal "unexpected logic type"
 
 (******************************************************************************)
 (** Memoization *)
@@ -277,6 +278,7 @@ let ty_of_logic_ty ?term ~profile lty =
     | Ctype ty -> number_ty_of_typ ~post:false ty
     | Lreal -> Real
     | Larrow _ -> Nan
+    | Lboolean -> Error.not_yet "boolean logic type"
     | Ltype _ -> Error.not_yet "user-defined logic type"
     | Lvar _ -> Error.not_yet "type variable"
   in
@@ -361,7 +363,7 @@ let rec type_term
        (and of course also covers the missing cases). Also enforce the invariant
        that every subterm is typed, even if it is not an integer. *)
     match t.term_node with
-    | TConst (Integer _ | LChr _ | LEnum _ | LReal _)
+    | TConst (Boolean _ | Integer _ | LChr _ | LEnum _ | LReal _)
     | TSizeOf _
     | TSizeOfStr _
     | TAlignOf _ ->
@@ -521,7 +523,7 @@ let rec type_term
               |_ -> if Options.Gmp_only.get() then Some Gmpz else None
             end
           | Lreal -> Some Real
-          | Ctype _| Ltype _| Larrow _ | Lvar _ -> None
+          | Lboolean | Ctype _ | Ltype _ | Larrow _ | Lvar _ -> None
         in
         ignore
           (type_term
@@ -615,7 +617,7 @@ let rec type_term
                          | TNamed _
                          | TComp _
                          | TBuiltin_va_list _))
-           | Some (Linteger | Lreal | Ltype _ | Lvar _ | Larrow _) ->
+           | Some (Lboolean | Linteger | Lreal | Ltype _ | Lvar _ | Larrow _) ->
              ty_of_interv
                ?ctx:ctx_body
                ~use_gmp_opt:(gmp && use_gmp_opt)
@@ -909,7 +911,7 @@ let extract_typ t ty =
   with Not_a_number ->
   match t.term_type with
   | Ctype _ as lty -> Logic_utils.logicCType lty
-  | Linteger | Lreal ->
+  | Lboolean | Linteger | Lreal ->
     Options.fatal "unexpected context NaN for term %a" Printer.pp_term t
   | Ltype _ -> Error.not_yet "unsupported logic type: user-defined type"
   | Lvar _ -> Error.not_yet "unsupported logic type: type variable"
diff --git a/src/plugins/e-acsl/src/code_generator/env.ml b/src/plugins/e-acsl/src/code_generator/env.ml
index e4f729209f8f92db3cdd65e46cf9c3ea7343d3dc..4842921bd11bccf7ab523e0e2540008a4ca0dda2 100644
--- a/src/plugins/e-acsl/src/code_generator/env.ml
+++ b/src/plugins/e-acsl/src/code_generator/env.ml
@@ -329,7 +329,7 @@ module Logic_binding = struct
       | None -> match logic_v.lv_type with
         | Ctype ty -> ty
         | Linteger -> Gmp_types.Z.t ()
-        | Ltype _ as ty when Logic_const.is_boolean_type ty -> Cil_const.charType
+        | Lboolean -> Cil_const.charType
         | Ltype _ | Lvar _ | Lreal | Larrow _ as lty ->
           let msg =
             Format.asprintf
diff --git a/src/plugins/e-acsl/src/code_generator/translate_terms.ml b/src/plugins/e-acsl/src/code_generator/translate_terms.ml
index b1abe02964f2dd81c1325fcbb930961cd1cec70b..c144bef77f7517182a82f149a16b058bc317ca06 100644
--- a/src/plugins/e-acsl/src/code_generator/translate_terms.ml
+++ b/src/plugins/e-acsl/src/code_generator/translate_terms.ml
@@ -51,6 +51,8 @@ let constant_to_exp ~loc env t c =
     Cil.mkString ~loc s, Analyses_types.Str_R
   in
   match c with
+  | Boolean b ->
+    (if b then Cil.one ~loc else Cil.zero ~loc), Analyses_types.C_number
   | Integer(n, _repr) ->
     let logic_env = Env.Logic_env.get env in
     let ity = Typing.get_number_ty ~logic_env t in
diff --git a/src/plugins/e-acsl/src/code_generator/translate_utils.ml b/src/plugins/e-acsl/src/code_generator/translate_utils.ml
index cea3235a866d0e0ec8355b138709f28edf10f86c..97bcb39caa54357fe75ffab17e217e70a093e7c2 100644
--- a/src/plugins/e-acsl/src/code_generator/translate_utils.ml
+++ b/src/plugins/e-acsl/src/code_generator/translate_utils.ml
@@ -272,6 +272,8 @@ let env_of_li ~adata ~loc kf env li =
       | Real -> Error.not_yet "real number"
     in
     adata, Env.add_stmt env stmt
+  | Lboolean ->
+    Env.not_yet env "booleans"
   | Ltype _ ->
     Env.not_yet env "user-defined logic type"
   | Lvar _ ->
diff --git a/src/plugins/e-acsl/src/libraries/interval_utils.ml b/src/plugins/e-acsl/src/libraries/interval_utils.ml
index 2b3a66396cfede22e832384babe3fabf91ad4006..7123a45a58c88d8d3aa1f3a834cf503d4264c03c 100644
--- a/src/plugins/e-acsl/src/libraries/interval_utils.ml
+++ b/src/plugins/e-acsl/src/libraries/interval_utils.ml
@@ -272,6 +272,7 @@ let interv_of_logic_typ = function
   | Ctype ty -> interv_of_typ ty
   | Linteger -> top_ival
   | Lreal -> Real
+  | Lboolean -> Error.not_yet "boolean"
   | Ltype _ -> Error.not_yet "user-defined logic type"
   | Lvar _ -> Error.not_yet "type variable"
   | Larrow _ -> Nan
diff --git a/src/plugins/e-acsl/src/libraries/misc.ml b/src/plugins/e-acsl/src/libraries/misc.ml
index e1ea93a8e4b694429e13b6f8980df08e7b9b5e1a..6252217ecbd5a291c9d4ef995b13fa48888c9294 100644
--- a/src/plugins/e-acsl/src/libraries/misc.ml
+++ b/src/plugins/e-acsl/src/libraries/misc.ml
@@ -165,7 +165,7 @@ let is_bitfield_pointers lty =
         | _ ->
           false
       end
-    | Ltype _ | Lvar _ | Linteger | Lreal | Larrow _ ->
+    | Ltype _ | Lvar _ | Lboolean | Linteger | Lreal | Larrow _ ->
       false
   in
   if Logic_const.is_set_type lty then
diff --git a/src/plugins/e-acsl/tests/format/oracle/printf.res.oracle b/src/plugins/e-acsl/tests/format/oracle/printf.res.oracle
index 6ea6f74635e3967de6c3b6d100e358da724b2b46..61c1a73899c027eb2f8c8723e43d98904a83659c 100644
--- a/src/plugins/e-acsl/tests/format/oracle/printf.res.oracle
+++ b/src/plugins/e-acsl/tests/format/oracle/printf.res.oracle
@@ -46,9 +46,13 @@
   is not yet supported.
   Ignoring annotation.
 [e-acsl] FRAMAC_SHARE/libc/string.h:196: Warning: 
-  E-ACSL construct `datacons' is not yet supported. Ignoring annotation.
+  E-ACSL construct `logic functions or predicates performing read accesses'
+  is not yet supported.
+  Ignoring annotation.
 [e-acsl] FRAMAC_SHARE/libc/string.h:204: Warning: 
-  E-ACSL construct `datacons' is not yet supported. Ignoring annotation.
+  E-ACSL construct `logic functions or predicates performing read accesses'
+  is not yet supported.
+  Ignoring annotation.
 [e-acsl] FRAMAC_SHARE/libc/string.h:192: Warning: 
   Some assumes clauses could not be translated.
   Ignoring complete and disjoint behaviors annotations.
diff --git a/src/plugins/e-acsl/tests/libc/oracle/mem.res.oracle b/src/plugins/e-acsl/tests/libc/oracle/mem.res.oracle
index d6ab15b134feef6c04847d8603b2d0b999f4f181..66d16674c03c91bd18f51a25b836c0cfc23e445f 100644
--- a/src/plugins/e-acsl/tests/libc/oracle/mem.res.oracle
+++ b/src/plugins/e-acsl/tests/libc/oracle/mem.res.oracle
@@ -7,7 +7,9 @@
   E-ACSL construct `assigns clause in behavior' is not yet supported.
   Ignoring annotation.
 [e-acsl] FRAMAC_SHARE/libc/string.h:151: Warning: 
-  E-ACSL construct `datacons' is not yet supported. Ignoring annotation.
+  E-ACSL construct `logic functions or predicates performing read accesses'
+  is not yet supported.
+  Ignoring annotation.
 [e-acsl] FRAMAC_SHARE/libc/string.h:138: Warning: 
   no assigns clause generated for function valid_read_or_empty because pointers as arguments is not yet supported
 [e-acsl] FRAMAC_SHARE/libc/string.h:137: Warning: 
diff --git a/src/plugins/e-acsl/tests/temporal/oracle/t_memcpy.res.oracle b/src/plugins/e-acsl/tests/temporal/oracle/t_memcpy.res.oracle
index c9851298903b4367411d8b16bb63c8b09e3a5e65..4e14e33da388847b5440e474374c1e29322cfdaa 100644
--- a/src/plugins/e-acsl/tests/temporal/oracle/t_memcpy.res.oracle
+++ b/src/plugins/e-acsl/tests/temporal/oracle/t_memcpy.res.oracle
@@ -7,7 +7,9 @@
   E-ACSL construct `assigns clause in behavior' is not yet supported.
   Ignoring annotation.
 [e-acsl] FRAMAC_SHARE/libc/string.h:151: Warning: 
-  E-ACSL construct `datacons' is not yet supported. Ignoring annotation.
+  E-ACSL construct `logic functions or predicates performing read accesses'
+  is not yet supported.
+  Ignoring annotation.
 [e-acsl] FRAMAC_SHARE/libc/string.h:113: Warning: 
   no assigns clause generated for function valid_read_or_empty because pointers as arguments is not yet supported
 [e-acsl] FRAMAC_SHARE/libc/string.h:112: Warning: 
diff --git a/src/plugins/eva/legacy/eval_terms.ml b/src/plugins/eva/legacy/eval_terms.ml
index 8c8361ee2f55a6982fdffceb878c2034b4d970d8..e230fd583c0245c6e38cda79ff4ae361932fbadf 100644
--- a/src/plugins/eva/legacy/eval_terms.ml
+++ b/src/plugins/eva/legacy/eval_terms.ml
@@ -503,11 +503,10 @@ let rec isLogicNonCompositeType t =
   match t with
   | Lvar _ | Larrow _ -> false
   | Ltype (info, _) ->
-    Logic_const.is_boolean_type t ||
     info.lt_name = "sign" ||
     (try isLogicNonCompositeType (Logic_const.type_of_element t)
      with Failure _ -> false)
-  | Linteger | Lreal -> true
+  | Lboolean | Linteger | Lreal -> true
   | Ctype t -> Cil.isScalarType t
 
 let rec infer_type = function
@@ -517,6 +516,7 @@ let rec infer_type = function
      | TFloat _ -> Cil_const.doubleType
      | _ -> t)
   | Lvar _ -> Cil_const.voidPtrType (* For polymorphic empty sets *)
+  | Lboolean -> Cil_const.boolType
   | Linteger -> Cil_const.intType
   | Lreal -> Cil_const.doubleType
   | Ltype _ | Larrow _ as t ->
@@ -1008,6 +1008,8 @@ let rec eval_term ~alarm_mode env t =
     ignore (env_state env lab);
     eval_term ~alarm_mode { env with e_cur = lab } t
 
+  | TConst (Boolean true) -> einteger Cvalue.V.singleton_one
+  | TConst (Boolean false) -> einteger Cvalue.V.singleton_zero
   | TConst (Integer (v, _)) -> einteger (Cvalue.V.inject_int v)
   | TConst (LEnum e) ->
     (match Cil.constFoldToInt e.eival with
@@ -1318,8 +1320,6 @@ let rec eval_term ~alarm_mode env t =
       match ctor_info.ctor_name with
       | "\\Positive" -> einteger positive_cvalue
       | "\\Negative" -> einteger negative_cvalue
-      | "\\true" -> einteger Cvalue.V.singleton_one
-      | "\\false" -> einteger Cvalue.V.singleton_zero
       | _ -> unsupported "logic inductive types"
     end
 
diff --git a/src/plugins/wp/Cvalues.ml b/src/plugins/wp/Cvalues.ml
index ef9898edec49d940caf3922d379b809c4e3f100f..fa1cdc224cda47682d4403edb0aef9043041c862 100644
--- a/src/plugins/wp/Cvalues.ml
+++ b/src/plugins/wp/Cvalues.ml
@@ -52,6 +52,8 @@ let rec constant = function
   | CStr _ | CWStr _ -> Warning.error "String constants not yet implemented"
 
 and logic_constant = function
+  | Boolean true -> e_true
+  | Boolean false -> e_false
   | Integer(z,_) -> e_bigint z
   | LChr c -> e_int64 (Ctypes.char c)
   | LReal r -> Cfloat.acsl_lit r
@@ -320,7 +322,7 @@ let cdomain obj =
 let ldomain ltype =
   match Logic_utils.unroll_type ~unroll_typedef:false ltype with
   | Ctype typ -> cdomain (Ctypes.object_of typ)
-  | Ltype _ | Lvar _ | Linteger | Lreal | Larrow _ -> None
+  | Ltype _ | Lvar _ | Lboolean | Linteger | Lreal | Larrow _ -> None
 
 (* -------------------------------------------------------------------------- *)
 (* --- Volatile                                                           --- *)
diff --git a/src/plugins/wp/Lang.ml b/src/plugins/wp/Lang.ml
index a026b4ac453d1401d74e562bf73f5eda18f12fd9..f90e9262f35bd6f38661d1d6b25211a638ecc686 100644
--- a/src/plugins/wp/Lang.ml
+++ b/src/plugins/wp/Lang.ml
@@ -158,6 +158,7 @@ let sort_of_ctype t = sort_of_object (Ctypes.object_of t)
 let sort_of_ltype t = match Logic_utils.unroll_type ~unroll_typedef:false t with
   | Ctype typ -> sort_of_ctype typ
   | Ltype _ | Lvar _ | Larrow _ -> Logic.Sdata
+  | Lboolean -> Logic.Sbool
   | Linteger -> Logic.Sint
   | Lreal -> Logic.Sreal
 
@@ -215,6 +216,7 @@ let atype lt ts =
 
 let rec tau_of_ltype t =
   match Logic_utils.unroll_type ~unroll_typedef:false t with
+  | Lboolean -> Logic.Bool
   | Linteger -> Logic.Int
   | Lreal -> Logic.Real
   | Ctype typ -> tau_of_ctype typ
@@ -222,7 +224,6 @@ let rec tau_of_ltype t =
   | Larrow _ ->
     Warning.error "array type non-supported(%a)"
       Printer.pp_logic_type t
-  | Ltype _ as b when Logic_const.is_boolean_type b -> Logic.Bool
   | Ltype(lt,lts) -> atype lt (List.map tau_of_ltype lts)
 
 let tau_of_return = function None -> Logic.Prop | Some t -> tau_of_ltype t
diff --git a/src/plugins/wp/LogicBuiltins.ml b/src/plugins/wp/LogicBuiltins.ml
index 20a6f81500acda300c516d1980d85e3d35849c5f..1dc34ddc4a07f1d6417cd89e2801991361b549c8 100644
--- a/src/plugins/wp/LogicBuiltins.ml
+++ b/src/plugins/wp/LogicBuiltins.ml
@@ -37,6 +37,7 @@ type builtin =
   | HACK of (F.term list -> F.term)
 
 type kind =
+  | B (* boolean *)
   | Z (* integer *)
   | R (* real *)
   | I of Ctypes.c_int
@@ -53,6 +54,7 @@ let okind = function
 let ckind typ = okind (object_of typ)
 
 let skind = function
+  | B -> Logic.Sbool
   | I _ | Z -> Logic.Sint
   | F _ | R -> Logic.Sreal
   | A -> Logic.Sdata
@@ -63,16 +65,19 @@ let rec lkind t =
   | Ltype({lt_name="set"},[t]) -> lkind t
   | Lreal -> R
   | Linteger -> Z
+  | Lboolean -> B
   | Ltype _ | Larrow _ | Lvar _ -> A
 
 let kind_of_tau = function
   | Qed.Logic.Int -> Z
   | Qed.Logic.Real -> R
+  | Qed.Logic.Bool -> B
   | _ -> A
 
 let pp_kind fmt = function
   | I i -> Ctypes.pp_int fmt i
   | F f -> Ctypes.pp_float fmt f
+  | B -> Format.pp_print_string fmt "bool"
   | Z -> Format.pp_print_string fmt "int"
   | R -> Format.pp_print_string fmt "real"
   | A -> Format.pp_print_string fmt "_"
diff --git a/src/plugins/wp/LogicBuiltins.mli b/src/plugins/wp/LogicBuiltins.mli
index 504bd54799b54d0221a031e157494710e58f6002..c72bc193ea3fca22da719070643ab0d8bea9a49b 100644
--- a/src/plugins/wp/LogicBuiltins.mli
+++ b/src/plugins/wp/LogicBuiltins.mli
@@ -30,6 +30,7 @@ open Lang
 type category = Lang.lfun Qed.Logic.category
 
 type kind =
+  | B                   (** boolean *)
   | Z                   (** integer *)
   | R                   (** real *)
   | I of Ctypes.c_int   (** C-ints *)
diff --git a/src/plugins/wp/LogicCompiler.ml b/src/plugins/wp/LogicCompiler.ml
index 4a3c76171f47c4673c4a21496848a3c04aa18ac6..86c92393cded77b4452cbf190526ca942ba8112e 100644
--- a/src/plugins/wp/LogicCompiler.ml
+++ b/src/plugins/wp/LogicCompiler.ml
@@ -854,15 +854,13 @@ struct
   let rec logic_type t =
     match Logic_utils.unroll_type ~unroll_typedef:false t with
     | Ctype _ -> ()
-    | Linteger | Lreal | Lvar _ | Larrow _ -> ()
+    | Lboolean | Linteger | Lreal | Lvar _ | Larrow _ -> ()
     | Ltype(lt,ps) ->
       List.iter logic_type ps ;
       if not (Typedefs.mem lt) then
         begin
           Typedefs.update lt None ;
-          if not (Lang.is_builtin lt) &&
-             not (Logic_const.is_boolean_type t)
-          then
+          if not (Lang.is_builtin lt) then
             let section = LogicUsage.section_of_type lt in
             let cluster = Definitions.section section in
             match section with
diff --git a/src/plugins/wp/LogicSemantics.ml b/src/plugins/wp/LogicSemantics.ml
index b49ce991d37a695a905a8bb2a2d3ee368d7548eb..77b875676c0626ad8f6cd09fa7ed82a70b1bbae0 100644
--- a/src/plugins/wp/LogicSemantics.ml
+++ b/src/plugins/wp/LogicSemantics.ml
@@ -284,7 +284,7 @@ struct
   let eqsort_of_type t =
     match Logic_utils.unroll_type ~unroll_typedef:false t with
     | Ltype({lt_name="set"},[_]) -> EQ_set
-    | Linteger | Lreal | Lvar _ | Larrow _ | Ltype _ -> EQ_plain
+    | Lboolean | Linteger | Lreal | Lvar _ | Larrow _ | Ltype _ -> EQ_plain
     | Ctype t ->
       match Ctypes.object_of t with
       | C_pointer _ -> EQ_loc
@@ -462,6 +462,7 @@ struct
 
   let rec cvsort_of_ltype src_ltype =
     match Logic_utils.unroll_type ~unroll_typedef:false src_ltype with
+    | Lboolean -> L_bool
     | Linteger -> L_integer
     | Lreal -> L_real
     | Ctype src_ctype ->
@@ -598,14 +599,14 @@ struct
       L.map Cmath.int_of_bool (C.logic env t)
     | L_real | L_cfloat _ | L_pointer _ | L_array _ ->
       Warning.error "@[Logic cast from (%a) to (%a) not implemented yet@]"
-        Printer.pp_logic_type src_ltype Printer.pp_logic_type Logic_const.boolean_type
+        Printer.pp_logic_type src_ltype Printer.pp_logic_type Lboolean
 
   let rec term_cast_to_ltype env dst_ltype t =
     match Logic_utils.unroll_type ~unroll_typedef:false dst_ltype with
     | Ctype typ-> term_cast_to_ctype env typ t
+    | Lboolean -> term_cast_to_boolean env t
     | Linteger -> term_cast_to_integer env t
     | Lreal -> term_cast_to_real env t
-    | Ltype _ as b when Logic_const.is_boolean_type b -> term_cast_to_boolean env t
     | Ltype({lt_name="set"},[elt_ltype]) -> (* lifting, set of elements ? *)
       term_cast_to_ltype env elt_ltype t
     | (Ltype _ | Lvar _ | Larrow _) as dst_ltype ->
@@ -691,9 +692,6 @@ struct
     | Tlambda _ ->
       Warning.error "Lambda-functions not yet implemented"
 
-    | TDataCons({ctor_name="\\true"},_) -> Vexp(e_true)
-    | TDataCons({ctor_name="\\false"},_) -> Vexp(e_false)
-
     | TDataCons(c,ts) ->
       let es = List.map (val_of_term env) ts in
       let r = match LogicBuiltins.ctor c with
diff --git a/src/plugins/wp/tests/wp_tip/oracle/split.res.oracle b/src/plugins/wp/tests/wp_tip/oracle/split.res.oracle
index 4a51426aad2d032bde154cb779aa18cd690dd965..9b698c9fd3ae57bb2cfa897496976ee7add29e4e 100644
--- a/src/plugins/wp/tests/wp_tip/oracle/split.res.oracle
+++ b/src/plugins/wp/tests/wp_tip/oracle/split.res.oracle
@@ -80,13 +80,13 @@
   ------------------------------------------------------------
 [wp:script:allgoals] 
   Goal Post-condition (file split.i, line 55) in 'test_step_peq':
-  Assume { (* Pre-condition *) Have: L_LQ = L_LP. }
+  Assume { (* Pre-condition *) Have: (L_LQ=true) <-> (L_LP=true). }
   Prove: P_S.
   
   ------------------------------------------------------------
 [wp:script:allgoals] 
   Goal Post-condition (file split.i, line 59) in 'test_step_pneq':
-  Assume { (* Pre-condition *) Have: L_LQ != L_LP. }
+  Assume { (* Pre-condition *) Have: !((L_LQ=true) <-> (L_LP=true)). }
   Prove: P_S.
   
   ------------------------------------------------------------
@@ -195,13 +195,13 @@
 [wp:script:allgoals] 
   Goal Post-condition (file split.i, line 107) in 'test_goal_eq':
   Assume { (* Pre-condition *) Have: P_S. }
-  Prove: L_LQ = L_LP.
+  Prove: (L_LQ=true) <-> (L_LP=true).
   
   ------------------------------------------------------------
 [wp:script:allgoals] 
   Goal Post-condition (file split.i, line 111) in 'test_goal_neq':
   Assume { (* Pre-condition *) Have: P_S. }
-  Prove: L_LQ != L_LP.
+  Prove: !((L_LQ=true) <-> (L_LP=true)).
   
   ------------------------------------------------------------
 [wp:script:allgoals] 
@@ -330,7 +330,7 @@
   typed_test_step_pneq_ensures subgoal:
   
   Goal Wp.Tactical.typed_test_step_pneq_ensures-0 (generated):
-  Assume { (* True/False *) When: (L_LQ=true) /\ (L_LP=false). }
+  Assume { (* True/False *) When: (L_LP=false) /\ (L_LQ=true). }
   Prove: P_S.
   
   ------------------------------------------------------------