I guess the following qualifies as one of meta-models you described. :)
I noticed that any programming challenge is a competition between a
program trying to prove (or rather trueify) a quantified boolean
formula, and another program trying to falsify it.
In general, a quantified boolean formula can be (or not?) reduced to
the form of:
forall u1. exists e1. forall u2. exists e2. ... f(u1,e1,u2,...)
The competition between participating problems will then proceed in
the following way:
- The falsifier program produces a value u1, for which, he thinks, the
further expression does not hold.
- The trueifier program takes u1 and produces e1, for which, he
thinks, the further expression holds.
- The falsifier takes u1 and e1 and produces u2, and so on, until all
the quantified variables has been assigned.
- Afterwards, the f function is evaluated by the judging system and
its value determines the winner.
However, for practical reasons (performance) it may be necessary to
write the formula in a different form, like this:
forall u1. checku1(u1) && !forall e1. checke1(u1,e1) && !forall u2.
checku2(u1,e1,u2). ... f(u1, e1, u2, ...)
(I have replaced "exists" with "!forall !" here so that the similarity
between the alternating quantifiers is more obvious)
This transformation will allow to terminate the trueifier/falsifier
message exchange early in case the judging system determines that one
of them has already lost.
I will provide some examples:
1. Standard programming problem in the form of QBF
forall test. testValid(test) && exists output. => outputCorrect(test, output)
Here the specification had to provide two functions: "testValid" and
"outputCorrect".
Specification falsifier is a testing framework (trying choosing a bad test)
Specification trueifier is a program submission (trying to satisfy
"outputCorrect" condition whatever test it is given)
2. An optimisation problem without a known solution:
forall test. testValid(test) && exists output. wellFormed(output) &&
!exists(output2). wellFormed(output2) && better(output2, output)
Here the specification only provides "testValid", "wellFormed", and
"better" functions, which is trivial.
The trueifier will be a normal solution to an optimisation problem.
The falsifier's job will be to provide a test data, wait for the
program output, and then to try and give a counter-example breaking
it.
3. Chess problems
A chess problem can be expressed in terms of QBF. Normally it will be
recursive, but I don't want to handle a recursive QBF case yet.
!exists w1. let statew1 = turn(initialState, w1) in isValid(statew1) &&
!exists b1. let stateb1 = turn(statew1, b1) in isValid(stateb1) &&
!exists w2. let statew2 = turn(stateb1, w2) in isValid(statew2) &&
!exists b2. let stateb2 = turn(statew2, b2) in isValid(stateb2) ...
(let it be 20 turns)
This formula, given the correct "turn", "initialState" and "isValid"
functions, will make the trueifier and falsifier play chess until one
of them is unable to make a valid move. Yes, this does not handle the
draw case. Can it be easily added?
This looked great to me at first, but in practice the time-out and
output overflow handling becomes a bit of a problem. For example, what
to do if a specification function times out? Or if a program is given
such an input for which the only possible correct output causes an
output overflow? One may say that such issues are specification
deficiencies, but the system will have to handle them and assign the
blame properly.
forall test. testValid(test) && exists output. outputCorrect(test, output)
In addition, as demonstrated, QBF carries some nice
human-understandable semantics, allowing to build almost natural
statements. This may be lost in a SAT conversion.
> my whole point is that the code
> should be a faceless modular web-service where each module handles
> certain kind of problems
That's a good idea. We should be keeping this in mind. However, I am
not convinced that the human web front-end should be using the web
API, but rather think that those could be just two different faces of
the same system.