Indeed, type_synonym is just the a synonym for the type specified, it does not introduce any new type.
consts just states you will define a new constant of the given type, without actually specifying how it is defined. (Note that since in Isabelle/HOL every type is inhabit, nothing has to be proved that such a constant can even exist). Afterwards you can define other functions, definitions, etc. which may already use the newly defined constant (drives
in your example, and drives_c
in my example below). At some point you can then actually provide the definition of the constant via defs.
type_synonym drives_t = "(int * nat) set"
consts drives_c :: "(int * nat) set"
(* test_drives already used drives_c *)
definition test_drives :: "int => bool" where
"test_drives x == (x, 5) : drives_c"
(* here, you actually define drives_c *)
defs drives_c_def: "drives_c == {(3,2), (7,5)}"
However, standard definitions can more directly be performed via definition.
definition drives_c :: drives_t where
"drives_c == {(3,2), (7,5)}"
Hope this helps,
René