91e16d69

By: Tom Sydney Kerckhove <syd@cs-syd.eu>

Add virtual assertions

`+ assert` cannot see virtual postings.  That is deliberate and consistent --
`balanceTransaction` feeds only real postings into `balancesForAssertions`, and
`balance/balanced/virtual-assertion.cent` pins it -- but it leaves an account
declared `virtual-only` with no assertable balance at all.  Asserting one
reported "The actual balance has no amount in the asserted currency", which
reads as a typo in the ledger rather than as a form that can never work there.

`+ assert virtual` names the other view.  Plain `+ assert` keeps meaning what it
meant, so `--virtual` still changes what you see rather than what an assertion
means.  It is legal on any account: the keyword names the view, not the kind of
account, and on an account that forbids virtual postings the two forms are
equivalent, which makes it redundant rather than wrong.

The scope is lexed as one compound token in the `<extra>` start code, which
leaves the assertion syntax untouched, so it composes with lot prices for free:

    + assert virtual assets:broker = +1 SWDA lot @ 500 EUR

The cost is that an account named exactly `virtual` cannot use the plain form,
because "assert virtual " outruns "assert " on that input.  Lexing `virtual` as
a keyword inside `<assertion>` fails on the same input for the same reason, so
this is a cost of the syntax rather than of the choice between the two.
`assets:virtual`, `virtual:sub` and `virtualx` are all unaffected.

The behavioural change is one balance map selection in `checkEntryAssertions`.

Two silent holes close with it, both needing the accounts map that assertion
compilation did not have:

  * CE_REAL_ASSERTION_NOT_ALLOWED, for a plain assertion on a virtual-only
    account, whose real balance is empty by construction so the assertion is
    either trivially true at zero or always false.
  * CE_UNDECLARED_ACCOUNT now covers assertions.  An assertion naming an account
    that does not exist used to read as zero and pass.