code
|
text
Parabellum
January 1, 2024
In the spirit of Galileoβs empiricismβwhich has been described as
the last resort
of the failed mathematician
βwe present Parabellum, a program for simulating
and quantifying the outcomes of military engagements. As mathematical fun
damentalists scribble away, attempting to find increasingly refined analytical
solutions to the sub-problems of strategy, this simulation program already now
addresses two of realityβs most persistent and pernicious shortcomings: its
apparent single-threadedness and its ambiguity.
Regarding ambiguity; it has been said that
facts speak for themselves with
overwhelming precision
[1]
. This is only exactly two thirds true:
1)
facts do
speak for themselves,
2)
with precision, but
3)
not overwhelmingly so. Take
the French military disaster (or perhaps rather the Viet Minh military success)
that was the fifty-six day siege known as the battle of Δiα»n BiΓͺn Phα»§. It was
preceded by a world soaked in facts, all speaking for themselves, but none with
the ferocity that posterity since brought them.
The French had built their fortress on the red earth of a valley encircled by a
jungle pregnant with subtle facts of the Viet Minhβs presence.
The French named their outposts after women; Beatrice, Gabrielle, Dominique
βthis one: CΓ©line. The Viet Minh came in the night and the rain, ghosts in
sandals, hauling artillery up slopes where no European gunner would think a
gun could go. In the night, the French watched the dark green hills erupt
with fire. As the days and weeks progressed, the French reinforcements would
continue, their birds of steel containing reports and gliding above a terrain
both discretely emitting the same fact: landing here is death. The airstrip
would became a graveyard for Dakota transports, the night sky made starless
with shrapnel and tracer, parachutes blooming in the nightβsome men landed
alive, some did not. The wounded call out in French, in Vietnamese, and in the
guttural language of the dying. On May 7, 1954, the last French radio message
crackled out: βThe enemy is everywhere. The situation is very graveβ
[2]
.
Regarding the single threadedness: Whether one (conservatively) subscribes
to the Copenhagen Interpretation of quantum mechanicsβwhere observation
collapses countless possible threads into a single, actual oneβor (more fash
ionably) the Many-Worlds Interpretation
[3]
, with its endlessly bifurcating
threads of reality, weβwhatever we might refer toβinhabit just one such
thread. Be it the only one or one among uncountably many, our experience
remains irrevocably confined to a single, linear trajectory.
How is one then to reason probabilistically about futureβpotential or eventual
βoutcomes under such ambiguous circumstances? From an information theo
retical point of view, where does one locate the French error at CΓ©line?
Parabellum, viewed in a vacuum, is thus a potentially parallelizable world
awaiting that which acts. Appendix A shows an example of single and paralel
trajectories. Recalling that counting is the bedrock of probability
[4]
, Parabel
lum proposes the following procedure:
1.
Create
π
simplified facsimiles of the reality about which one wishes to reason
2.
Set these in concurrent motion, recording
π‘
π
=
{
(
π
0
,
π
0
)
,
β¦
,
(
π
π
,
π
π
)
}
3.
Compute statistics over
{
π‘
1
,
β¦
,
π‘
π
}
to divine the value of strategy
π
(
π
)
β
π
Each process can be thought of as consisting of a world (yielding states
π
) and
that which operates within it (yielding actions
π
).
A | CODE
from jax import random, vmap, lax
import parabellum as pb
rng, key = random.split(random.PRNG(0))
env, scene = pb.env.init_fn({"place": "ΔiΓͺn BiΓͺn PhΓΉ"})
Load in jax programs and parabellum, and declare global varaibles
def action_fn(rng):
coord = random.normal(rng, (env.num_units, 2))
shoot = random.bernoulli(rng, 0.5, shape=(env.num_units,))
return pb.types.Action(coord=coord, shoot=shoot)
Function for taking random action
def step_fn(state, rng):
action = action_fn(rng)
obs, state = env.step(rng, scene, state, action)
return state, (state, action)
Function for taking steps in a scan.
rngs = random.split(rng, (n_steps, n_sims))
Random numbers for simualtions, and parallel simulations
obs, state = env.reset(rngs[0][0], scene)
state, seq = lax.scan(step, state, rngs[0])
Running
π
trajectories in parallel, we merely use
vmap
:
obs, state = vmap(env.reset, in_axes=(0, None))(rngs[0], scene)
state, seq = lax.scan(vmap(step), state, rngs)
REFERENCES
[1]
J. Conrad,
Typhoon
. United Kingdom: Pall Mall Magazine, 1902.
[2]
P. W. Shull, βThe Battle of Dien Bien Phu: Strategic, Operational and Tac
tical Failure:,β Fort Belvoir, VA, Apr. 1999. doi:
10.21236/ADA363910
.
[3]
J. L. Borges, βThe Garden of Forking Paths,β
Ficciones
. Grove Press, New
York, 1962.
[4]
R. L. Schilling,
Measures, Integrals and Martingales
, 2nd ed. Cambridge:
Cambridge university press, 2017.