Computational Strategy: A Basic Sketch
I will attempt to outline a bit of what, at the simplest level, a strategic model would look like. Since I have been talking a lot about this (entry 1, entry 2), I might as well briefly outline an extremely simplified sketch of what an agent in the mode I am talking about would have and do. This is intended to be highly abstract and define the outline of a possible simulation agent architecture in terms of a basic formalism used in defense analysis: the capabilities and intentions threat model. Capabilities are what the agent has, intentions are what it wants to do.
This isn’t quite pseudocode but uses a programming language-like formalism for the sketch. Note that only a few top functions and are defined here — the implementation of each function — a function ends with a () to hold inputs — is not covered here and only alluded to. If you think that this idea has some merit, the programming implementation is (as they say), left as an exercise to the reader.
Assume that we are assuming a single, representative agent in a conventional warfare simulation. Let us assume that we utilize the capabilities and intentions threat model to define a Commander object with data fields holding objects of relevance.
Class Commander(parameters to be initialized with)
Commander.capabilities(an ordered list of military assets)
Commander.intentions(an ordered list of fixed goals)
We will add a set of political objectives defined in terms of conditions where each political objective looks like the following (note: Blue and Red are terms for one’s own side and adversary).
politicalObjective = Red must not do X
politicalObjective = Blue must do Y
We can revise the political objectives a bit to include notions of cost and scope.
politicalObjective = Red must not do X, unless cost of opposing Red exceeds Y
We can likely turn the “cost” into a general constraint set, so let’s just call the political objective: “constraints” from here on forward as a way to combine both goal-driven and constraint-driven shaping of the agent’s search space during its own behavior generation process. , We generate a theory of victory from a predefined repetoire of tactics, constraints, and what the agent believes the opponent’s capabilities and intentions are. We also pass the strategy selection function a priori theories of victory that the agent has institutionalized in some shape or form through strategic practice, and we also add a plan base to reflect the fact that some kind of prewar campaign planning has occurred (e.g., a CONPLAN in US military structure).
Function strategySelection(constraints, tactics, planBase, opponent.capabilities, opponent.intentions, theoriesOfVictory): simulateOpponent(opponent.capabilities, opponent.intentions);
create goalPerception(constraints, opponent.threat);
generateTheoryofVictory(goalPerception, theoriesOfVictory);
modifyPlanBase(theoryofVictory, tactics);
updateCapabilities(theoryofVictory, operationalPlan);
updateIntentions(theoryofVictory, operationalPlan);
What has happened here is that the agent function first uses a crude forward simulation of what it believes the opponent will do and creates a threat out of it. Since, of course, the agent’s capabilities and intentions model of the opponent will reflect noise and bias, we might filter the agent’s perception of the opponent through noise function that has some element of bias towards particular evaluations. Regardless, the forward simulation itself will be crude and likely be based on self-simulation (“what I would do if I were the enemy”). The forward simulation returns a threat perception of the opponent.
Next, we take pre-existing notions of what theories of victory are possible and the constraints/political objectives and pass them to a function that matches theories of victory to constraints and returns a basic theory of how to achieve strategic success. After that, we use the believed threat and our simulated constraints as an input to a process that looks at a broad set of predefined plans. Taking the theory of victory and available tactics as input, the plan base of existing contingency plans is assessed and then translated (with tactics as input) into an operational plan consisting of a tactical sequence. An operational plan is returned. We then update the agent’s capabilities and intentions with the theory of victory and operational plan as a guide, pruning capabilities and intentions that do not fit with it.
So, in all, our command agent looks like this:
Class Commander(parameters to be initialized with)
Commander.capabilities(an ordered list of military assets)
Commander.intentions(an ordered list of fixed goals) Function strategySelection(parameter list)
What else do we need? At a basic level, an agent is able to generate a behavior sequence of operations to accomplish a higher-level goal. These sequences may vary according to strategic type. For example, let us look at the distinctions between cumulative and sequential strategy as per J.C. Wylie.
Function planCumulativeStrategy(subGoal, blueRegion, redRegion, blueForceStrength, redForceStrength, acceptableLogisticCost): if redRegion - blueRegion >= acceptableLogisticCost:
create bomberTaskForce;
bomberTaskForce.calibrateAttackWaveParameters();
bomberTaskForce.allocateTargets();
bomberTaskForce.allocateLogisticalResources();
for attackWave in bomberTaskForce.attackWaves:
attackWave.bombingOffensive();
Here, in this block, we see some basic elements of generating a plan for a cumulative strategy (in this case, a bombing offensive). Let us assume that the cumulative strategy achieves a subgoal defined from the main goal in a given theater of operations where blue and red forces are fighting. Both blue and red’s regions are their definitive supply bases and staging areas. If a cumulative strategy has been selected by a higher-order function, the planning function for it is activated. If the opponent region and the commander region’s (for simplicity’s sake here just a numerical value defining a point on the map)’s distance is less than or equal to the logistical cost of projecting power, the method creates a bomber task force, allocates the targets, and allocates the desired logistical resources. After that, we activate and launch all bomber waves.
This, however, is just a basic sketch. In order to really represent a cumulative strategy, we would need to make some big modifications. Because cumulative strategies function as a loop (do X until desired strategic effect is achieved), we could run this strategy as a repeating process of a basic set of randomly ordered tactical actions (to simulate the probabilistic manner in which each wave of bombers would utilize those tactics on the battlefield). Depending on how we implement the bombers, we might also make each bomber wave run asynchronously and with a limited degree of concurrency to simulate the nonlinear nature of air campaigns.
Next, we look at a sequential strategy.
Function planSequentialStrategy(goalOrdering, blueFormation, tactics); for formation in blueFormation:
formatation.generateStaffPlan(goalOrdering, tactics,);
formation.moveToStagingAreas(staffPlan);
formation.offensiveOperations(staffPlan);
Let us now assume, also for the sake of simplicity, that a subgoal has already been selected in a theater of operations. Let us assume that the sequential strategy achieves a linear ordering of sub-subgoals that have been previously decomposed by a process that specifies what ought to be achieved in a desired theater of operation. Next, what ought to be done is to allocate tasks to the variegated elements of the theater army we have given the agent.
We might represent this force by partitioning goals to each formation (at the highest level of abstraction we can get away with) in terms of objectives to achieve and then watch them locally attempt to realize them in order. Because the strategy is sequential, certain actions by formation objects are not possible unless other formations have achieved their specific goal partition.We might implement this as a hierarchy of objectives that each agent has access to in some shape or form.
Because the plan might change dynamically due to the position of the agents, we might implement a replanning mechanism that updates the goal ordering in real-time based on the actual combat results. For example, if formation X is struggling to break through in its area of operations, and if the priority of it breaking through is worth it, we could implement a function that diverts some air support from formation Y’s operational area to pulverize formation X’s opposition, and then re-task the air resources when done.
This sketch and conceptual schema is purely notional — implementations have and will look remarkably different. However, it also gives a flavor of the kind of engineering challenges involved in the simulation. Moreover, it stresses that while many tactics can accomplish broad plans, behaviors, and procedures, those procedures themselves do not fluctuate during the duration of the conflict. Agents “go to the war with the army they have,” so to speak. Broad elements of declarative and procedural knowledge define and constrain how the agent moves through its search space when acting.