See \<^file>\<open>$ISABELLE_HOME/src/Pure/General/utf8.ML\<close> and\<^file>\<open>$ISABELLE_HOME/src/Pure/General/utf8.scala\<close>.
-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
module Isabelle.UTF8 ( setup, setup3,
Recode (..)
) where
import qualified System.IO as IO
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Encoding
import qualified Data.Text.Encoding.Error as Error
import Data.ByteString (ByteString)
import qualified Isabelle.Bytes as Bytes
import Isabelle.Bytes (Bytes)
setup :: IO.Handle -> IO () setup h = do
IO.hSetEncoding h IO.utf8
IO.hSetNewlineMode h IO.noNewlineTranslation
import System.Environment (lookupEnv)
import Data.Maybe (fromMaybe)
import qualified Data.Text as Text
import Data.Text (Text)
import qualified Data.Text.Lazy as Lazy
import Data.String (IsString)
import qualified Data.List.Split as Split
import qualified Isabelle.Symbol as Symbol
import qualified Isabelle.Bytes as Bytes
import Isabelle.Bytes (Bytes)
import qualified Isabelle.UTF8 as UTF8
{- functions -}
(|>) :: a -> (a -> b) -> b
x |> f = f x
(|->) :: (a, b) -> (a -> b -> c) -> c
(x, y) |-> f = f x y
(#>) :: (a -> b) -> (b -> c) -> a -> c
(f #> g) x = x |> f |> g
(#->) :: (a -> (c, b)) -> (c -> b -> d) -> a -> d
(f #-> g) x = x |> f |-> g
{- lists -}
fold :: (a -> b -> b) -> [a] -> b -> b
fold _ [] y = y
fold f (x : xs) y = fold f xs (f x y)
fold_rev :: (a -> b -> b) -> [a] -> b -> b
fold_rev _ [] y = y
fold_rev f (x : xs) y = f x (fold_rev f xs y)
fold_map :: (a -> b -> (c, b)) -> [a] -> b -> ([c], b)
fold_map _ [] y = ([], y)
fold_map f (x : xs) y = let
(x', y') = f x y
(xs', y'') = fold_map f xs y' in (x' : xs', y'')
single :: a -> [a]
single x = [x]
the_single :: [a] -> a
the_single [x] = x
the_single _ = undefined
singletonM :: Monad m => ([a] -> m [b]) -> a -> m b
singletonM f x = the_single <$> f [x]
map_index :: ((Int, a) -> b) -> [a] -> [b]
map_index f = map_aux 0 where
map_aux _ [] = []
map_aux i (x : xs) = f (i, x) : map_aux (i + 1) xs
get_index :: (a -> Maybe b) -> [a] -> Maybe (Int, b)
get_index f = get_aux 0 where
get_aux _ [] = Nothing
get_aux i (x : xs) = case f x of
Nothing -> get_aux (i + 1) xs
Just y -> Just (i, y)
separate :: a -> [a] -> [a]
separate s (x : xs@(_ : _)) = x : s : separate s xs
separate _ xs = xs;
{- string-like interfaces -}
class (IsString a, Monoid a, Eq a, Ord a) => StringLike a where
space_explode :: Char -> a -> [a]
trim_line :: a -> a
gen_trim_line :: Int -> (Int -> Char) -> (Int -> a -> a) -> a -> a
gen_trim_line n at trim s = if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then trim (n - 2) s
else if n >= 1 && Symbol.is_ascii_line_terminator (at (n - 1)) then trim (n - 1) s
else s
instance StringLike String where
space_explode :: Char -> String -> [String]
space_explode c = Split.split (Split.dropDelims (Split.whenElt (== c)))
trim_line :: String -> String
trim_line s = gen_trim_line (length s) (s !!) take s
instance StringLike Textwhere
space_explode :: Char -> Text -> [Text]
space_explode c str = ifText.null str then []
else ifText.all (/= c) str then [str]
else map Text.pack $ space_explode c $ Text.unpack str
trim_line :: Text -> Text
trim_line s = gen_trim_line (Text.length s) (Text.index s) Text.take s
instance StringLike Lazy.Textwhere
space_explode :: Char -> Lazy.Text -> [Lazy.Text]
space_explode c str = ifLazy.null str then []
else ifLazy.all (/= c) str then [str]
else map Lazy.pack $ space_explode c $ Lazy.unpack str
trim_line :: Lazy.Text -> Lazy.Text
trim_line = Lazy.fromStrict . trim_line . Lazy.toStrict
instance StringLike Bytes where
space_explode :: Char -> Bytes -> [Bytes]
space_explode c str = if Bytes.null str then []
else if Bytes.all_char (/= c) str then [str]
else
explode (Bytes.unpack str) where
explode rest = case span (/= (Bytes.byte c)) rest of
(_, []) -> [Bytes.pack rest]
(prfx, _ : rest') -> Bytes.pack prfx : explode rest'
trim_line :: Bytes -> Bytes
trim_line s = gen_trim_line (Bytes.length s) (Bytes.char . Bytes.index s) Bytes.take s
class StringLike a => STRING a where make_string :: a -> String instance STRING String where make_string = id instance STRING Textwhere make_string = Text.unpack instance STRING Lazy.Textwhere make_string = Lazy.unpack instance STRING Bytes where make_string = UTF8.decode
class StringLike a => TEXT a where make_text :: a -> Text instanceTEXT String where make_text = Text.pack instanceTEXTTextwhere make_text = id instanceTEXTLazy.Textwhere make_text = Lazy.toStrict instanceTEXT Bytes where make_text = UTF8.decode
class StringLike a => BYTES a where make_bytes :: a -> Bytes instance BYTES String where make_bytes = UTF8.encode instance BYTES Textwhere make_bytes = UTF8.encode instance BYTES Lazy.Textwhere make_bytes = UTF8.encode . Lazy.toStrict instance BYTES Bytes where make_bytes = id
show_bytes :: Show a => a -> Bytes
show_bytes = make_bytes . show
show_text :: Show a => a -> Text
show_text = make_text . show
{- strings -}
proper_string :: StringLike a => a -> Maybe a
proper_string s = if s == ""then Nothing else Just s
enclose :: StringLike a => a -> a -> a -> a
enclose lpar rpar str = lpar <> str <> rpar
quote :: StringLike a => a -> a
quote = enclose "\"" "\""
space_implode :: StringLike a => a -> [a] -> a
space_implode s = mconcat . separate s
implode_space :: StringLike a => [a] -> a
implode_space = space_implode " "
commas, commas_quote :: StringLike a => [a] -> a
commas = space_implode ", "
commas_quote = commas . map quote
split_lines :: StringLike a => a -> [a]
split_lines = space_explode '\n'
cat_lines :: StringLike a => [a] -> a
cat_lines = space_implode "\n"
trim_split_lines :: StringLike a => a -> [a]
trim_split_lines = trim_line #> split_lines #> map trim_line
{- getenv -}
getenv :: Bytes -> IO Bytes
getenv x = do
y <- lookupEnv (make_string x)
return $ make_bytes $ fromMaybe "" y
getenv_strict :: Bytes -> IO Bytes
getenv_strict x = do
y <- getenv x if Bytes.null y then
errorWithoutStackTrace $ make_string ("Undefined Isabelle environment variable: " <> quote x)
else return y \<close>
is_eof, not_eof :: Symbol -> Bool
is_eof = Bytes.null
not_eof = not . is_eof
{- ASCII characters -}
is_ascii_letter :: Char -> Bool
is_ascii_letter c = 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
is_ascii_digit :: Char -> Bool
is_ascii_digit c = '0' <= c && c <= '9'
is_ascii_hex :: Char -> Bool
is_ascii_hex c = '0' <= c && c <= '9' || 'A' <= c && c <= 'F' || 'a' <= c && c <= 'f'
is_ascii_quasi :: Char -> Bool
is_ascii_quasi c = c == '_' || c == '\''
is_ascii_blank :: Char -> Bool
is_ascii_blank c = c `elem` (" \t\n\11\f\r" :: String)
is_ascii_line_terminator :: Char -> Bool
is_ascii_line_terminator c = c == '\r' || c == '\n'
is_ascii_letdig :: Char -> Bool
is_ascii_letdig c = is_ascii_letter c || is_ascii_digit c || is_ascii_quasi c
is_ascii_identifier :: String -> Bool
is_ascii_identifier s =
not (null s) && is_ascii_letter (head s) && all is_ascii_letdig s
{- explode symbols: ASCII, UTF8, named -}
is_utf8 :: Word8 -> Bool
is_utf8 b = b >= 128
is_utf8_trailer :: Word8 -> Bool
is_utf8_trailer b = 128 <= b && b < 192
is_utf8_control :: Word8 -> Bool
is_utf8_control b = 128 <= b && b < 160
(|>) :: a -> (a -> b) -> b
x |> f = f x
explode :: Bytes -> [Symbol]
explode string = scan 0 where
byte = Bytes.index string
substring i j = if i == j - 1 then Bytes.singleton (byte i)
else Bytes.pack (map byte [i .. j - 1])
n = Bytes.length string
test pred i = i < n && pred (byte i)
test_char pred i = i < n && pred (Bytes.char (byte i))
many pred i = if test pred i then many pred (i + 1) else i
maybe_char c i = if test_char (== c) i then i + 1 else i
maybe_ascii_id i = if test_char is_ascii_letter i then many (is_ascii_letdig . Bytes.char) (i + 1)
else i
scan i = if i < n then let
b = byte i
c = Bytes.char b in
{-encoded newline-} if c == '\r' then "\n" : scan (maybe_char '\n' (i + 1))
{-pseudo utf8: encoded ascii control-}
else if b == 192 && test is_utf8_control (i + 1) && not (test is_utf8 (i + 2)) then Bytes.singleton (byte (i + 1) - 128) : scan (i + 2)
{-utf8-}
else if is_utf8 b then let j = many is_utf8_trailer (i + 1) in substring i j : scan j
{-named symbol-}
else if c == '\\' && test_char (== '<') (i + 1) then let j = (i + 2) |> maybe_char '^' |> maybe_ascii_id |> maybe_char '>' in substring i j : scan j
{-single character-}
else Bytes.singleton b : scan (i + 1)
else [] \<close>
print_real :: Double -> Bytes
print_real x = let s = show x in case span (/= '.') s of
(a, '.' : b) | List.all (== '0') b -> make_bytes a
_ -> make_bytes s
import Isabelle.Library
import qualified Isabelle.Properties as Properties
import qualified Isabelle.Value as Value
import qualified Isabelle.Bytes as Bytes
import Isabelle.Bytes (Bytes)
blockN :: Bytes
blockN = \<open>Markup.blockN\<close>
block :: Bool -> Int -> T
block c i =
(blockN,
(if c then [(consistentN, Value.print_bool c)] else []) <>
(if i /= 0 then [(indentN, Value.print_int i)] else []))
breakN :: Bytes
breakN = \<open>Markup.breakN\<close>
break :: Int -> Int -> T
break w i =
(breakN,
(if w /= 0 then [(widthN, Value.print_int w)] else []) <>
(if i /= 0 then [(indentN, Value.print_int i)] else []))
Source positions starting from 1; values <= 0 mean "absent". Count Isabelle
symbols, not UTF8 bytes nor UTF16 characters. Position range specifies a
right-open interval offset .. end_offset (exclusive).
See \<^file>\<open>$ISABELLE_HOME/src/Pure/General/position.ML\<close>.
-}
put_id :: Bytes -> T -> T
put_id id pos = pos { _id = id }
id :: Bytes -> T
id id = put_id id start
id_only :: Bytes -> T
id_only id = put_id id none
{- count position -}
count_line :: Symbol -> Int -> Int
count_line "\n" line = if_valid line (line + 1)
count_line _ line = line
count_column :: Symbol -> Int -> Int
count_column "\n" column = if_valid column 1
count_column s column = if Symbol.not_eof s then if_valid column (column + 1) else column
count_offset :: Symbol -> Int -> Int
count_offset s offset = if Symbol.not_eof s then if_valid offset (offset + 1) else offset
symbol :: Symbol -> T -> T
symbol s pos =
pos {
_line = count_line s (_line pos),
_column = count_column s (_column pos),
_offset = count_offset s (_offset pos) }
symbol_explode :: BYTES a => a -> T -> T
symbol_explode = fold symbol . Symbol.explode . make_bytes
symbol_explode_string :: String -> T -> T
symbol_explode_string = symbol_explode
{- shift offsets -}
shift_offsets :: Int -> T -> T
shift_offsets shift pos = pos { _offset = offset', _end_offset = end_offset' } where
offset = _offset pos
end_offset = _end_offset pos
offset' = if invalid offset || invalid shift then offset else offset + shift
end_offset' = if invalid end_offset || invalid shift then end_offset else end_offset + shift
{- markup properties -}
get_string :: Properties.T -> Bytes -> Bytes
get_string props name = fromMaybe "" (Properties.get_value Just props name)
get_int :: Properties.T -> Bytes -> Int
get_int props name = fromMaybe 0 (Properties.get_value Value.parse_int props name)
add_content :: Tree -> Buffer.T -> Buffer.T
add_content tree = case unwrap_elem tree of
Just (_, ts) -> fold add_content ts
Nothing -> case tree of
Elem (_, ts) -> fold add_content ts Text s -> Buffer.add s
See \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/xml.ML\<close>.
-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
module Isabelle.XML.Encode (
A, T, V, P,
int_atom, bool_atom, unit_atom,
tree, properties, string, int, bool, unit, pair, triple, list, option, variant
) where
import Data.Maybe (fromJust)
import Isabelle.Library
import Isabelle.Bytes (Bytes)
import qualified Isabelle.Value as Value
import qualified Isabelle.Properties as Properties
import qualified Isabelle.XML as XML
type A a = a -> Bytes
type T a = a -> XML.Body
type V a = a -> Maybe ([Bytes], XML.Body)
type P a = a -> [Bytes]
See \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/xml.ML\<close>.
-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
module Isabelle.XML.Decode (
A, T, V, P,
int_atom, bool_atom, unit_atom,
tree, properties, string, int, bool, unit, pair, triple, list, option, variant
) where
import Isabelle.Library
import Isabelle.Bytes (Bytes)
import qualified Isabelle.Value as Value
import qualified Isabelle.Properties as Properties
import qualified Isabelle.XML as XML
type A a = Bytes -> a
type T a = XML.Body -> a
type V a = ([Bytes], XML.Body) -> a
type P a = [Bytes] -> a
err_atom = error "Malformed XML atom"
err_body = error "Malformed XML body"
{- atomic values -}
int_atom :: A Int
int_atom s = caseValue.parse_int s of
Just i -> i
Nothing -> err_atom
import qualified Data.List as List
import Data.Word (Word8)
import Isabelle.Library
import qualified Isabelle.Bytes as Bytes
import Isabelle.Bytes (Bytes)
import qualified Isabelle.Markup as Markup
import qualified Isabelle.XML as XML
import qualified Isabelle.Buffer as Buffer
import qualified Isabelle.Bytes as Bytes
import qualified Isabelle.Name as Name
import Isabelle.Name (Name)
import qualified Isabelle.Properties as Properties
import qualified Isabelle.Markup as Markup
import Isabelle.XML.Classes
import qualified Isabelle.XML as XML
import qualified Isabelle.YXML as YXML
type Names = [(Name, (Name, Name))] -- external name, kind, internal name
data T = Completion Properties.T Int Names -- position, total length, names
formatted :: T -> Bytes
formatted = YXML.string_of_body . symbolic
unformatted :: T -> Bytes
unformatted = Buffer.build_content . out where
out (Block markup _ _ prts) = let (bg, en) = YXML.output_markup markup in Buffer.add bg #> fold out prts #> Buffer.add en
out (Break _ wd) = Buffer.add (Bytes.spaces wd)
out (Str s) = Buffer.add s
{- derived operations to create formatting expressions -}
force_nat n | n < 0 = 0
force_nat n = n
str :: BYTES a => a -> T
str = Str . make_bytes
brk_indent :: Int -> Int -> T
brk_indent wd ind = Break (force_nat wd) ind
dest_internal, dest_skolem :: Name -> Maybe Name
dest_internal = Bytes.try_unsuffix "_"
dest_skolem = Bytes.try_unsuffix "__"
clean_index :: (Name, Int) -> (Name, Int)
clean_index (x, i) = case dest_internal x of
Nothing -> (x, i)
Just x' -> clean_index (x', i + 1)
clean :: Name -> Name
clean x = fst (clean_index (x, 0))
{- contextfor used names -}
newtype Context = Context (Map Name (Maybe Name)) {-declared names with latest renaming-}
declare :: Name -> Context -> Context declare x (Context names) = Context ( let a = clean x inif Map.member a names then names else Map.insert a Nothing names)
make_context :: [Name] -> Context
make_context used = fold declare used context
{- generating fresh names -}
bump_init :: Name -> Name
bump_init str = str <> "a"
bump_string :: Name -> Name
bump_string str = let
a = Bytes.byte 'a'
z = Bytes.byte 'z'
bump (b : bs) | b == z = a : bump bs
bump (b : bs) | a <= b && b < z = b + 1 : bs
bump bs = a : bs
variant :: Name -> Context -> (Name, Context)
variant name ctxt = let
vary x = case declared ctxt x of
Nothing -> x
Just x' -> vary (bump_string (fromMaybe x x'))
(x, n) = clean_index (name, 0)
(x', ctxt') = if not (is_declared ctxt x) then (x, declare x ctxt)
else let
x0 = bump_init x
x' = vary x0
ctxt' = ctxt |> declare_renamed (x0, x') in (x', ctxt') in (x' <> Bytes.pack (replicate n underscore), ctxt')
variant_list :: [Name] -> [Name] -> [Name]
variant_list used names = fst (make_context used |> fold_map variant names) \<close>
import Isabelle.Library
import qualified Isabelle.Name as Name
import Isabelle.Name (Name)
infixr 5 --> infixr --->
{- typesand terms -}
type Indexname = (Name, Int)
type Sort = [Name]
data Typ =
Type (Name, [Typ])
| TFree (Name, Sort)
| TVar (Indexname, Sort)
deriving (Show, Eq, Ord)
data Term =
Const (Name, [Typ])
| Free (Name, Typ)
| Var (Indexname, Typ)
| Bound Int
| Abs (Name, Typ, Term)
| App (Term, Term)
| OFCLASS (Typ, Name)
deriving (Show, Eq, Ord)
{- free and bound variables -}
type Free = (Name, Typ)
lambda :: Free -> Term -> Term
lambda (name, typ) body = Abs (name, typ, abstract 0 body) where
abstract lev (Free (x, ty)) | name == x && typ == ty = Bound lev
abstract lev (Abs (a, ty, t)) = Abs (a, ty, abstract (lev + 1) t)
abstract lev (App (t, u)) = App (abstract lev t, abstract lev u)
abstract _ t = t
declare_frees :: Term -> Name.Context -> Name.Context
declare_frees (Free (x, _)) = Name.declare x
declare_frees (Abs (_, _, b)) = declare_frees b
declare_frees (App (t, u)) = declare_frees t #> declare_frees u
declare_frees _ = id
incr_boundvars :: Int -> Term -> Term
incr_boundvars inc = if inc == 0 then id else incr 0 where
incr lev (Bound i) = if i >= lev then Bound (i + inc) else Bound i
incr lev (Abs (a, ty, b)) = Abs (a, ty, incr (lev + 1) b)
incr lev (App (t, u)) = App (incr lev t, incr lev u)
incr _ t = t
subst_bound :: Term -> Term -> Term
subst_bound arg = subst 0 where
subst lev (Bound i) = if i < lev then Bound i
else if i == lev then incr_boundvars lev arg
else Bound (i - 1)
subst lev (Abs (a, ty, b)) = Abs (a, ty, subst (lev + 1) b)
subst lev (App (t, u)) = App (subst lev t, subst lev u)
subst _ t = t
dest_lambda :: Name.Context -> Term -> Maybe (Free, Term)
dest_lambda names (Abs (x, ty, b)) = let
(x', _) = Name.variant x (declare_frees b names)
v = (x', ty) in Just (v, subst_bound (Free v) b)
dest_lambda _ _ = Nothing
strip_lambda :: Name.Context -> Term -> ([Free], Term)
strip_lambda names tm = case dest_lambda names tm of
Just (v, t) -> let (vs, t') = strip_lambda names t' in (v : vs, t')
Nothing -> ([], tm)
{- type andterm operators -}
type_op0 :: Name -> (Typ, Typ -> Bool)
type_op0 name = (mk, is) where
mk = Type (name, []) is (Type (c, _)) = c == name is _ = False
type_op1 :: Name -> (Typ -> Typ, Typ -> Maybe Typ)
type_op1 name = (mk, dest) where
mk ty = Type (name, [ty])
dest (Type (c, [ty])) | c == name = Just ty
dest _ = Nothing
type_op2 :: Name -> (Typ -> Typ -> Typ, Typ -> Maybe (Typ, Typ))
type_op2 name = (mk, dest) where
mk ty1 ty2 = Type (name, [ty1, ty2])
dest (Type (c, [ty1, ty2])) | c == name = Just (ty1, ty2)
dest _ = Nothing
op0 :: Name -> (Term, Term -> Bool)
op0 name = (mk, is) where
mk = Const (name, []) is (Const (c, _)) = c == name is _ = False
op1 :: Name -> (Term -> Term, Term -> Maybe Term)
op1 name = (mk, dest) where
mk t = App (Const (name, []), t)
dest (App (Const (c, _), t)) | c == name = Just t
dest _ = Nothing
op2 :: Name -> (Term -> Term -> Term, Term -> Maybe (Term, Term))
op2 name = (mk, dest) where
mk t u = App (App (Const (name, []), t), u)
dest (App (App (Const (c, _), t), u)) | c == name = Just (t, u)
dest _ = Nothing
typed_op0 :: Name -> (Typ -> Term, Term -> Maybe Typ)
typed_op0 name = (mk, dest) where
mk ty = Const (name, [ty])
dest (Const (c, [ty])) | c == name = Just ty
dest _ = Nothing
typed_op1 :: Name -> (Typ -> Term -> Term, Term -> Maybe (Typ, Term))
typed_op1 name = (mk, dest) where
mk ty t = App (Const (name, [ty]), t)
dest (App (Const (c, [ty]), t)) | c == name = Just (ty, t)
dest _ = Nothing
typed_op2 :: Name -> (Typ -> Term -> Term -> Term, Term -> Maybe (Typ, Term, Term))
typed_op2 name = (mk, dest) where
mk ty t u = App (App (Const (name, [ty]), t), u)
dest (App (App (Const (c, [ty]), t), u)) | c == name = Just (ty, t, u)
dest _ = Nothing
binder :: Name -> (Free -> Term -> Term, Name.Context -> Term -> Maybe (Free, Term)) binder name = (mk, dest) where
mk (a, ty) b = App (Const (name, [ty]), lambda (a, ty) b)
dest names (App (Const (c, _), t)) | c == name = dest_lambda names t
dest _ _ = Nothing
import qualified Isabelle.Name as Name
import Isabelle.Term
mk_forall_op :: Typ -> Term -> Term; dest_forall_op :: Term -> Maybe (Typ, Term)
(mk_forall_op, dest_forall_op) = typed_op1 \<open>\<^const_name>\<open>Pure.all\<close>\<close>
mk_forall :: Free -> Term -> Term; dest_forall :: Name.Context -> Term -> Maybe (Free, Term)
(mk_forall, dest_forall) = binder\<open>\<^const_name>\<open>Pure.all\<close>\<close>
mk_equals :: Typ -> Term -> Term -> Term; dest_equals :: Term -> Maybe (Typ, Term, Term)
--> --------------------
--> maximum size reached
--> --------------------
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.32Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.