A szokásos legegyszerűbb példa:
A BT_IO az alapvető kiíró/beolvasó műveletekért felelős. Ennek metódusa a writeString, ami a standard outputra ír. A főprogram egy egyszerű üres program.
A példa letölthető innen.Egy példa a lehetséges típuskonstrukciókra a jEdit beépített B fordítójához adott példák közül.
3 függvényt deklarál, ezek CONCRETE-ak, azaz definiálni kell őket. A függvény xx-re tesz megkötést, és a visszatérési értéket specifikálja (szorítja meg) típusokra.
Itt meg van adva a konkrét inicializáció (itt kötelező is), és a függvény konkrét leírása, ami megfelel a specifikációnak. Ezt a megfelelést a B típusellenőrzők vizsgálják.
Egyszerű üres gép.
A gép egyszerűen kiírja a kapott logikai, és egész értéket. A kapott eredmény FALSE és 0.
Egy nagyobb lélegzetű példa. A Singleton (egyke) tervminta megvalósítása gépekkel. Ebből is látható, hogy ugyan nem objektumorientált a láthatóságok így is jól kezelhetőek, és az öröklődés is megoldható így.
A példa letölthető innen.Ez a gép felel meg a Singleton osztálynak. Adott benne egy adat, ehhez hasonlóan bármennyi adattagot fel lehet használni. Az osztály objektumának létezését, vagy nem létezését itt egy boolean típusú adattaggal helyettesítjük. Ezekre az implementált programban is szükség lesz, így CONCRETE_VARIABLES részben deklaráljuk őket. Kezdetben nem létezik példányosított osztály, így az "exist" hamis értékű, az adattag tetszőleges.
3 művelete van a gépnek. Az első kettő az osztály eljárásait helyettesíti (művelet a Singleton adattagján, jelen esetben értékadás, valamint lekérdezés), az utolsó megadja, hogy már létezik-e az Egyke (ez utóbbi egy egyszerű lekérdezés). Az adattag lekérdezését csak létező Egyke esetén értelmezzük, ekkor ez is egyszerű adattag lekérdezés. Az adaton értelmezett művelet ebben a példában egy egyszerű értékadás, azzal a módosítással, hogy ha még nem létezett az Singleton, akkor az "exist" értékét igazra állítja.
Ebben az esetben nem lett volna szükség két esetre bontani a műveletet, de ha nem egyszerű értékadás történik, akkor szükség lehet erre. A szimultán értékadást az implementáció során ki kell küszöbölni.
Az előzőleg definiált absztrakt alapgép implementációja. Az inicializációt meg kell ismételni, és a műveleteket új formában kell megadni (felül is lehetne definiálni ezeket). Itt nem szerepelhetnek nem determinisztikus műveletek, és szimultán értékadások.
Az eljárások implementációja:
Értékadás: az alapprogrambeli SELECT-es szerkezetet itt más programnyelvekből ismertebb IF-THEN-ELSE szerkezettel írjuk le, a szimultán értékadást pedig több egyszerű értékadást szekvenciájaként (a sorrend jelen esetben nem számít).
A két másik művelet egyszerű lekérdezés az implementációnak megfelelő szintaxissal.
A feltételeket implementált gépeknél nem kell kiírni. A fordító az alapgépek alapján ellenőriz.
Az interface látja a Singleton gépet, a SEES működése biztosítja, hogy ez a gépet akár SEES, akár INCLUDE tagban szerepel, csak ő példányosodik esetleg többször a Singleton gép nem, abból mindig csak 1 marad.
A két művelet az Egyke gép műveleteinek lehetséges interfaceket deklarálnak (a lekérdezésnél vissza kell adni valamilyen értéket, hogy a visszatérési érték típusát meg lehessen határozni, ezért adok vissza 0-t (NAT típus)).
Az előző gép megvalósítása. Inicializálja a Singleton gépet. A műveleteknek adhat egy új külső felületet. Jelen esetben ezek a felületek egyszerűen csak meghívják az Egyke megfelelő műveleteit, de itt bármilyen változtatás, akár eltérő paraméterezés is lehetséges.
A példa letölthető innen.Az alábbiakban mutatunk egy példát a specifikációra és arra, hogy milyen lemmák generálódnak belőle, ha a B4free programot használjuk.
A Proof Obligation Generator a helyettesítésekkel definiált szemantika segítségével generálja a bebizonyítandó lemmákat. A B-módszer által meghatározott (a szemantikából következő) lemmákat a lehető legegyszerűbb alakra hozza. A legegyszerűbb esetekben maga a Proof Obligation Generator is beláthatja egy lemmáról, hogy teljesül, például, ha az egyszerűsítések során a formula az azonosan igazra egyszerűsödik.
A forráskód:
Közvetlenül az inicializáció után az invariánsnak igaznak kell lennie, ami az [I]P formulával fogalmazható meg, ahol az I az inicializáló értékadás, a P pedig az invariáns.
Esetünkben az állítás a következő:
[rfree := 1..5] (rfree ⊆ 1..10)
A Proof Obligation Generator elvégzi a helyettesítést, így lesz a bizonyítandó lemma végleges alakja:
(1..5 ⊆ 1..10)
A műveleteknek meg kell őrizniük az invariánst.
Általánosan: I ∧ P ⇒ [S]I, ahol az I az invariáns, az S a művelet törzse, P pedig a művelet előfeltétele, ha a művelet PRE-THEN-ELSE alakú (esetünkben ilyen alakú).
A példában a bizonyítandó állítás:
rfree ⊆ 1..10 ∧ r ∈ rfree ⇒
[PRE r ∈ rfree THEN rfree := rfree - r END]
(rfree ⊆ 1..10)
A PRE-THEN-END szerkezet definíciója: [PRE P THEN G END] Q ⇔ P ∧ [G] Q
A Proof Obligation Generator elvégzi a helyettesítést és egy triviális egyszerűsítést:
rfree ⊆ 1..10 ∧ r ∈ rfree ⇒
r ∈ rfree ∧ [ rfree := rfree - {r} ] (rfree ⊆ 1..10)
rfree ⊆ 1..10 ∧ r ∈ rfree ⇒ [ rfree := rfree - {r} ] (rfree ⊆ 1..10)
rfree ⊆ 1..10 ∧ r ∈ rfree ⇒ (rfree - {r} ⊆ 1..10)
A bizonyítandó lemma alakja tehát a következő:
rfree ⊆ 1..10 ∧ r ∈ rfree ⇒ (rfree - {r} ⊆ 1..10)