This could provide a good starting point, since the structure of the diagrams is simply a cross with four regions that themselves can contain similar crosses, you can simply define a structure to represent this nesting and a recursive function to draw such structures. In my implementation I just use the head c
to indicate a cross:
dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
cross[mid_, scale_] := {
Thickness[0.02 scale],
Line[{scale {-1, -1} + mid, scale {1, 1} + mid}],
Line[{scale {1, -1} + mid, scale {-1, 1} + mid}]
}
rDraw[True, mid_, scale_] := Disk[mid, scale]
rDraw[False, ___] := {}
rDraw[c[a__], mid_: {0, 0}, scale_: 1] := {cross[mid, scale],
Sequence @@ MapIndexed[
rDraw[#1, mid + scale dirs[[#2[[1]]]], 0.45 scale] &, {a}]}
So then you can create a diagram via:
With[{t = True, f = False},
rDraw@c[t, f, c[f, c[f, t, c[f, t, f, t], f], t, f], f] // Graphics
]

Now it is just a question of converting expressions like (A&B) or !C
into this c[...]
structure.
Here's a small graph of some simple operations:
With[{t = True, f = False},
Graphics[rDraw[#2], PlotLabel -> #1] & @@@ {
{"and", c[f, t]},
{"Nand", c[t, f, t, t]},
{"or", c[t, t, t]},
{"Nor", c[f, f, f, t]}
} // GraphicsRow
]
