I am trying to write a story generator in Clingo.
I am trying to say "new characters can be born if existing characters give birth to them." I define new characters as entity(<int\>)
, which is the best way I could think of to representing entities. I cannot hardcode this as varying number of entities can be created in a story.
My code
is :
% Create instances of time, only 3 for testing
time(0..2).
% Arrow of time flows forward
next_t(T, T+1) :- time(T), time(T+1).
% Entity 1 exists at time 0.
entity(1, 0).
% If an entity ever existed, that ID is taken and cannot be assigned to
% other entities
entity_id(ID) :- entity(ID, _).
% If an entity exists, he can give birth to a new entity
% The ID of the new entity will be 1 more than ID of all current entities.
birth(X, Y, T) :- entity(Y, T), X = #max{X1+1:entity_id(X1)}, time(T).
% At each time instant, only 1 entity can be born, as only 1 event can happen per time instant.
% This also should prevent infinite entities to be created.
:- birth(X1, _, T), birth(Y1, _, T), X1!=Y1.
% In case of a birth, create a new entiti the next time instant.
entity(X, T1) :- birth(X, _, T), next(T, T1).
#show entity_id/1.
#show entity/2.
#show birth/3 .
However, output is :
entity_id(1) entity(1,0) birth(2,1,0)
entity(2, 1)
is never created, nor are entity(3, 2)
or entity(4, 3)
.
What am I doing wrong? Is there a better way to do this?
You seem to be thinking that ASP statements happen in order from first to last or something like that. But in fact they're just rules about a collection of atoms. The rules always hold. In particular, the rule:
says nothing about duplicates. It just says that for every entity which has an ID
ID
,ID
is anentity_id
. If you want to encode the rule that eachID
is used once, you should write it as:Also you try to construct "ID's" which are "one more than all current entities", but there's no such thing as "current" entities. All we have to guide us are the time-steps.
Let's try writing this in a way that keeps our timesteps explicit throughout.
Running this I find there are 5 models.