Install the `cm-super`

package and put `\usepackage{etex,microtype}`

in your preamble.

Enable clickable links with `\usepackage{hyperref}`

and use `\autoref{thm:foo}`

.

Write `\emph{this}`

, not `{\em this}`

. Similarly, use `\textbf{this}`

, not `{\bf this}`

.

For displayed formulas, use `\[ ... \]`

, not `$$ ... $$`

.

Use `chktex`

, ideally integrated into your editor.

And for a lot more, see https://www.ctan.org/pkg/l2tabu-english.

]]>I really like email. It is one of the few federated communication systems that is used by most internet users.

However, there are two kinds of problems with email recently. First, structurally: email has been almost centralized by the biggest advertisement company, spam is still a huge problem, and running an email server on your own is quite tedious. Second, and the topic of this post: individual emails are often full of nonsense that should not be there. Additionally, people seem to be getting lazier and lazier before hitting the send button.

Here comes a wish list how I like my email, sorted by the amount of effort I ask from you.

Just use plain text for your email. I care about its content, not whether you want me to read it in olive Comic Sans on a beige background. Moreover, HTML emails are a security disaster.

Use a spellchecker and ensure that you write names correctly. I will also make an effort to spell your name correctly in my reply. If you really find something hard to spell or type, copy-paste it. But note that HTML formatting might make it obvious that you copied something from somewhere else — another reason not to use it.

I don’t care which typewriter, smartphone, tablet, mail client, operating system, anti-virus software or coffee brand you use. Hence you do not have to finish your email with a signature advertising it. Often these signatures are added automatically, so you might not even know that you are sending around advertisements. Moreover, such signatures are sometimes a sign that your anti-virus is doing a man-in-the-middle attack against you.

An email should be self-contained and not “call home” each time I open it. When my email program tells me it had to block remote content, I will no longer read your email with an open mind. Also, please just forget about the “receipt confirmation” feature. If you should know that I read your email, I will tell you.

This goes together with the previous comment, because automatic crapware signatures tend to include remote content. Why should your anti-virus company get a notification each time I read your email?

The saying “If you are not paying, you are the product” is very true for email. Where are your emails stored and what is the business model of the company storing them? Should I be careful what I write because it will be used to ~~optimize advertisements~~ manipulate you?

Depending on the context in which you are contacting me, please use the right account. Say, if you are a student and your university provides an address for you, please use it: j.kees@university.tld makes a much better impression than kittenlover98@aol.com.

Finally, if you really want me to be happy when I get your email, please use PGP. Mare sure to also *sign* your email and make your public key available.

*Thank you.*

Since this commit the famous puzzle is also one of the examples included in SMCDEL, a symbolic model checker for DEL. Here I will explain the basics usage of SMCDEL and highlight the differences between explicit and symbolic model checking.

Like DEMO, also SMCDEL is meant to be used as a Haskell module. There is also a command-line and a web interface which are easier to use, but as of now they provide less functionality. It would be a hassle to encode Cheryl’s Birthday in the format needed by those interfaces, so here we will use Haskell directly.

We start by importing a Haskell library for lists and two modules from SMCDEL: the language and the symbolic methods for S5. The latter choice makes sense because the puzzle is only about knowledge, not belief.

```
module SMCDEL.Examples.Cheryl where
import Data.List
import SMCDEL.Language
import SMCDEL.Symbolic.S5
```

Before doing anything with SMCDEL we define the set of all possibilities, i.e. all birthdays. This is exactly the same as in the DEMO version, but for readability we also introduce a type alias.

```
type Possibility = (Int, String)
possibilities :: [Possibility]
possibilities =
[ (15,"May"), (16,"May"), (19,"May")
, (17,"June"), (18,"June")
, (14,"July"), (16,"July")
, (14,"August"), (15,"August"), (17,"August") ]
```

Recall that DEMO offers many different atomic propositions like `P Int`

, `Q Int`

, `R Int`

and `Info a`

. Especially the `Info a`

propositions are a very convenient and powerful tool. Unfortunately, such nominal propositions are not available in SMCDEL. The language in SMCDEL provides only one set of atomic propositions given by `P Int`

. This restriction is due to the encoding with Binary Decision Diagrams.

Still, also without `Info a`

propositions we can make our life easy: we define abbreviations in Haskell so that we can write formulas more easily. For example, we fix that `P 17`

means “The day of Cheryl’s birthday is 17.” and that `P 8`

means “The month of Cheryl’s birthday is August.”

```
dayIs :: Int -> Prp
dayIs = P
monthIs :: String -> Prp
monthIs "May" = P 5
monthIs "June" = P 6
monthIs "July" = P 7
monthIs "August" = P 8
monthIs _ = undefined
```

We then combine our atomic propositions to form more complex formulas. For example, the command `thisPos (15,"August")`

will give us the conjunction `Conj [PrpF (P 15), PrpF (P 8)]`

saying that Cheryl’s birthday is the 15th of August. The second formula `knWhich i`

says that agent *i* *knows* Cheryl’s birthday. This the same as `knowsBday`

in the `DEMO`

version and also here we define it as a big disjunction. This is not optimal, but given the small model size in this puzzle, it does not hurt.

```
thisPos :: Possibility -> Form
thisPos (d,m) = Conj $
(PrpF (dayIs d) : [ Neg (PrpF $ dayIs d') | d' <- nub (map fst possibilities) \\ [d] ]) ++
(PrpF (monthIs m) : [ Neg (PrpF $ monthIs m') | m' <- nub (map snd possibilities) \\ [m] ])
knWhich :: Agent -> Form
knWhich i = Disj [ K i (thisPos pos) | pos <- possibilities ]
```

Now, instead of an initial Kripke model, for SMCDEL we need a *knowledge structure* modelling the start of the puzzle. A knowledge structure is the symbolic analogue of a Kripke model. Recall that a Kripke model contains a set of worlds *w*_{1}, *w*_{2}, etc. and valuations like *p*_{1} : true, *p*_{2} : false, etc. for each world. Instead of listing all this information explicitly, a knowledge structure contains a *summary* of the whole set of worlds.

**The main trick of symbolic model checking is to replace the explicit list of worlds with a boolean formula and then say: My worlds are all boolean assignments satisfying this formula.**

Well, and there are some more ingredients. First, there are many tricks to find and modify this boolean formula. Second, instead of a *formula* we only need the boolean *function* it represents and this can be represented as a Binary Decision Diagram.

A knowledge structure now consists of three parts:

- a list of propositions called the vocabulary:
`allprops`

, - the aforementioned boolean formula:
`statelaw`

, and - for each agent a list which propositions that agent observes:
`obs`

.

Let us compare this again to a Kripke model. The vocabulary and state law together replace the set of worlds and the valuation function. The observational variables replace the accessibility relation.

(Maybe you are now wondering whether a knowledge structure is just a different way to write down a Kripke model. The answer is yes. Think of knowledge structures as a data structure to store Kripke models.)

Enough theory, here is the initial knowledge structure for Cheryl’s Birthday puzzle:

```
start :: KnowStruct
start = KnS allprops statelaw obs where
allprops = sort $ nub $ map (dayIs . fst) possibilities ++
map (monthIs . snd) possibilities
statelaw = boolBddOf $ Conj
[ Disj (map thisPos possibilities)
, Conj [ Neg $ Conj [thisPos p1, thisPos p2]
| p1 <- possibilities, p2 <- possibilities, p1 /= p2 ] ]
obs = [ ("Albert" , nub $ map (monthIs . snd) possibilities)
, ("Bernard", nub $ map (dayIs . fst) possibilities) ]
```

It is easy to check that `allprobs`

is the list `map P [5,6,7,8,14,15,16,17,18,19]`

. The formula `statelaw`

essentially says “The birthday must be one of the `possibilities`

, but it cannot be two different ones at the same time.” To encode the knowledge of the agents, we let Albert observe all atomic propositions about the day and Bernard those about the month. An equivalent and sometimes more intuitive way to read observational variables is this: an agent observes a variable iff the agent *knows whether* that variable is true.

Now we will update the ~~model~~ structure with public announcements, given by the dialogue in the puzzle. The announced formulas are exactly the same as in the DEMO implementation, with small syntax adaptations. Instead of the `upd_pa`

function in DEMO we now use the `update`

function in SMCDEL. In fact, `update`

is polymorphic such that it also accepts action models or transformers, but here it is given a formula and will thus execute a public announcement.

First Albert says: “I don’t know when Cheryl’s birthday is and I know that Bernard does not know.” To model this we update with the following conjunction:

Then Bernard says: “Now I know when Cheryl’s birthday is.”

Finally, Albert says: “Now I also know when Cheryl’s birthday is.”

We can now get the solution by asking for the remaining states:

```
$ stack ghci src/SMCDEL/Examples/Cheryl.hs
λ> statesOf round3
[[P 7,P 16]]
```

To get the solution in a more readable form, we can write a little helper function:

```
cherylsBirthday :: String
cherylsBirthday = m ++ " " ++ show d ++ "th" where
[(d,m)] = filter
(\(d',m') -> [monthIs m', dayIs d'] `elem` statesOf round3)
possibilities
```

Spoiler alert!

```
λ> cherylsBirthday
"July 16th"
```

If you want to learn more about the internals of SMCDEL, please have a look at the source code and documentation or my PhD thesis. The first chapter also describes the basics of Dynamic Epistemic Logic.

]]>One of the “Android calling home” functions that is tricky to disable or remove, is the check for internet connectivity after joining a WiFi network.

Every Android device requests `https://connectivitycheck.gstatic.com/generate_204`

after connecting to a wireless network. This page hosted by google is empty and returns a 204 status code. Most captive portals use status code 200 to serve a page or 203 to redirect somewhere, hence this works as a simple check whether the device is behind a portal.

I now wanted to keep my Fairphone 2 from connecting to this server. Setting the checked URL to some nonsense would disable the check, but then Android would claim that it has no internet connection all the time, showing a dreaded exclamation mark icon.

But which server should I use instead?

As I am running multiple webservers for my own and friends’ websites, the way to go was to set up a link that generates 204 results myself.

To create the correct response I made a simple file `204.php`

as follows.

Alternatively, if PHP is not available, one can also add a simple redirect to the websever configuration, in my case Apache:

```
<VirtualHost *:80>
...
RedirectMatch 204 (.*)/204$
...
</VirtualHost>
```

Then, in a root terminal on the phone I entered the following two commands, from *pat_512* in the Fairphone Forum (see links below).

```
settings put global captive_portal_http_url "http://198.51.100.24/204"
settings put global captive_portal_https_url "https://example.com/204.php"
```

In fact, this could also be used to track a device, recording on the server when it was in which wifi, or rather when it had which public IP address. Setting the URL differently on different devices could then be used to distinguish their requests.

**Related Links**

`DEMO_S5`

from http://homepages.cwi.nl/~jve/software/demo_s5 and a modified version of `KRIPKEVIS`

from https://w4eg.de/malvin/illc/kripkevis.
You can also download a PDF version of this report and the source files.

We first define the set of all possibilities:

```
allpos :: [(Int, String)]
allpos = [ (15,"May"), (16,"May"), (19,"May"), (17,"June"), (18,"June"),
(14,"July"), (16,"July"), (14,"August"), (15,"August"), (17,"August") ]
```

This forms the set of worlds in our initial model. Moreover, also the set of actual worlds is the full set, hence `allpos`

occurs twice in the definition below. The two elements of `rels`

define the epistemic relations of Albert and Bernard. Instead of listing explicitly which possibilities they can distinguish we use haskell functions to say that they confuse the same day and the same month, respectively.

```
initCheryl :: EpistM (Int,String)
initCheryl = Mo allpos [a,b] [] rels allpos where
rels = [ ( a, groupBy ((==) `on` snd) allpos )
, ( b, groupBy ((==) `on` fst) (sortBy (compare `on` fst) allpos) ) ]
```

This is the initial model with all possibilities:

The formula saying that *i* knows Cheryl’s birthday is defined as the disjunction over all statements of the form “Agent i knows that the birthday is s”:

Now we update the model three times, using the function `upd_pa`

for public announcements. First with Albert: I don’t know when Cheryl’s birthday is and I know that Bernard does not know.

The second announcement by Bernard: “Now I know when Cheryl’s birthday is.”

Finally, Albert says: “Now I also know when Cheryl’s birthday is.”

Lastly, this helper function uses `texModel`

from `KRIPKEVIS`

to generate the drawings:

```
myTexModel :: EpistM (Int,String) -> String -> IO String
myTexModel (Mo states _ _ rels pointed) fn =
texModel showState showAgent showVal ""
(VisModel states rels [(s,0)|s<-states] pointed) fn
where
showState (n,string) = (show n) ++ string
showAgent i = if i==a then "Albert" else "Bernard"
showVal _ = ""
```