<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Introducing ASP recipes and ASP Chef</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Mario Alviano</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Davide Cirimele</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Luis Angel Rodriguez Reiners</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>DEMACS, University of Calabria</institution>
          ,
          <addr-line>Via Bucci 30/B, 87036 Rende (CS)</addr-line>
          ,
          <country country="IT">Italy</country>
        </aff>
      </contrib-group>
      <abstract>
        <p>Answer Set Programming (ASP) is gaining popularity in the Knowledge Representation and Reasoning community thanks to its high-level modeling capabilities that ease the fast prototyping of systems addressing complex tasks. On the other hand, ASP is not a general purpose programming language and therefore it is usually employed for specific tasks of possibly long and articulated pipelines. This article introduces the notion of ASP recipe, a chain of ingredients combining computational tasks typical of ASP with other operations of data manipulation and visualization. ASP recipes are at the core of ASP Chef, a simple, intuitive web app for analysing answer sets that is designed to ease the creation of pipelines of operations over sequences of interpretations.</p>
      </abstract>
      <kwd-group>
        <kwd>eol&gt;answer set programming</kwd>
        <kwd>modular programming</kwd>
        <kwd>knowledge visualization</kwd>
        <kwd>UX design</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>Knowledge Representation and Reasoning applications are characterized by complex domains
whose features of interest are properly encoded in a computer-readable format so that
automatic manipulation, synthesis and sophisticated reasoning tasks can be addressed by eficient,
specialized engines [1]. In this context, Answer Set Programming (ASP) [2] is gaining popularity
among researchers and practitioners thanks to its declarative approach to problem solving that
combines linguistic high-level constructs typical of logic-based programming languages as well
as advanced solving algorithms for combinatorial search and optimization [3].</p>
      <p>
        Despite its theoretical unrestricted computational capabilities, allowing to simulate any
Turing machine when uninterpreted function symbols are used [4], ASP is not designed or
intended to be a general programming language. As such, ASP must be employed to address
specific tasks of a broader pipeline, and therefore tasks addressed by ASP engines are expected
to receive their input from other modules of the pipeline, possibly implemented in a diferent
paradigm, and are as well expected to produce output that will be consumed by subsequent
modules of the pipeline, again possibly implemented in diferent paradigms. (For example, [ 5]
reports a framework for controlling articulated robots involving several modules, among them
several that are powered by ASP.)
connected(
        <xref ref-type="bibr" rid="ref1 ref2">1,2</xref>
        ).
connected(
        <xref ref-type="bibr" rid="ref1 ref4">1,4</xref>
        ).
connected(
        <xref ref-type="bibr" rid="ref2 ref3">2,3</xref>
        ).
connected(
        <xref ref-type="bibr" rid="ref3 ref4">3,4</xref>
        ).
connected(
        <xref ref-type="bibr" rid="ref3 ref5">3,5</xref>
        ).
connected(
        <xref ref-type="bibr" rid="ref4 ref5">4,5</xref>
        ).
connected(
        <xref ref-type="bibr" rid="ref5 ref6">5,6</xref>
        ).
1 connected(X,Y) :- connected(Y,X). % symmetric closure
2 {select(T)} :- town(T). % guess solution
3 :∼ select(T). [1@1, T] % minimize selected towns
4 % no path of length  not including any selected town
5 :- townsintravel(N), path_length(_,N).
6 path_length((T,nil), 1) :- town(T), not select(T).
7 path_length((T',(T,X)), L+1) :- path_length((T,X), L), townsintravel(N), L &lt; N, connected(T,T'),
not select(T'), not in_path(T',X).
8 in_path(T, (T,X)) :- path_length((T,X), _).
9 in_path(T',(T,X)) :- path_length((T,X), _), in_path(T',X).
      </p>
      <p>As a matter of fact, experienced ASP practitioners are used to map data from one format to
the format accepted by ASP engines, and to map the output produced by ASP engines to some
other format that is suitable to be presented to the end-user or to be further processed in the
implemented pipeline. The problem of implementing such mapping procedures occurs at each
ASP module of the pipeline and therefore it represents a not negligible task for development
teams. On the one hand, the problem almost disappears if the pipeline is actually composed by
a single ASP module, essentially either in the unrealistic hypothesis that the input and output
format of ASP engines is suitable for the application to develop, or because there are only two
mapping procedures to implement. On the other hand, even in such cases pretending to use ASP
only in this way might severely limit its scope of application. In fact, without proper mechanisms
enabling the exchange of data between ASP modules and modules of diferent nature, ASP
practitioners, especially those at an early stage, may be tempted to use ASP as a single entity
and as such find it convenient only to address computationally complex combinatorial problems,
rather than as a solid formalism to be employed in broader pipelines.</p>
      <p>This article introduces the notion of ASP recipe as a chain of ingredients that are essentially the
instantiation of diferent operations. An operation can be one of the typical computational tasks
for which ASP engines find a natural application, such as combinatorial search and optimization,
some data manipulation procedure, or also some data visualization procedure. The idea is to
provide a formalism in which the user can employ ASP directly by specifying a set of logic
rules, but also indirectly via the operations that are implemented using an ASP engine.
1 connected(X,Y) :- connected(Y,X).
2 {path(1,T) : town(T)} = 1.
3 {path(I+1,T') : connected(T,T')} = 1
:</p>
      <p>path(I,T), townsintravel(N), I &lt; N.
4 :- path(I,T), path(J,T), I &lt; J.
5 in_path(T) :- path(_,T).
1 {select(T)} :- town(T).
2 :∼ select(T). [1@1, T]
3 ok(P) :- in_path(P,T), select(T).
4 :- in_path(P,_), not ok(P).</p>
      <p>For example, consider Fighting with the gang of Billy the Kid, a problem from the LP/CP
Programming Contest series (https://github.com/lpcp-contest/). The input comprises a positive
integer , and a graph representing towns and streets. The goal is to select a minimum number
of towns such that each path visiting  distinct towns includes at least one of the selected towns.
Intuitively, the selected towns are those to monitor in order to catch bandits moving among 
towns for their illicit activities. An instance and its solution are shown in Figure 1. The problem
can be solved by a monolithic ASP encoding guessing (and minimizing) the selected towns, and
enforcing that no path of  non-selected towns does exist; such a requirements can be enforced
relying on uninterpreted function symbols, as shown in Figure 2. Approaching the problem
with an ASP recipe may first rely on an ASP program whose answer sets are paths of  towns,
enumerate all of them, then pack all paths as the input for another ASP program addressing the
required combinatorial optimization task. Figure 3 reports such ASP programs, and Section 6
further elaborates on this solution to the problem.</p>
      <p>One of the dificulties to face in order to enable the composition of linear chains of ingredients
is the format to adopt for the input and output of each operation. Adopting diferent formats
leads to increased complexity in terms of design of the notion of ASP recipe as well as in their
composition, as essentially compatibility of formats must be taken into account at each chain
junction. Such a dificulty is circumvented by adopting a uniform format for input and output of
all operations, that is, sequences of interpretations. Additionally, operations can have parameters
to customize their behavior, and also have side output to enable inspection and visualization of
intermediate states of the evaluation of ASP recipes.</p>
      <p>This work also introduces ASP Chef, a web app designed to implement possibly long pipelines
in which ASP is often used as a core engine to address several computational tasks and putting
in practice the notion of ASP recipe. We remark here that the main enabling mechanism adopted
by ASP Chef to ease the application of ASP in possibly long pipelines is a uniform format for
the input and output of each operation in the pipeline. Thanks to such a uniformity, the several
operations implemented in ASP Chef can be combined in any order, and new operations can be
accommodated easily in the future. Actually, among the operations already implemented in
ASP Chef, there are operations to ease the embedding of structured and semi-structured data,
so that the restriction to the format of sequences of interpretations becomes almost immaterial.
In fact, the restriction is bypassed by operations relying on Base64 encoding as Base64 strings
are valid terms for ASP engines, and they are conceived to encode any binary data. For example,
the ParseCSV operation maps a comma-separated values (CSV) content into a sequence of facts
that is added to each interpretation in input to produce an output enabling the processing of
the CSV data (see Section 4.6). The ASP encoding itself can be composed and manipulated by
means of the Encode operation, which essentially encodes in Base64 an arbitrary content and
extends each interpretation in input with a new fact carrying such data (see Section 4.5). In
the next sections, after introducing some background (Section 2), we introduce the notions of
operation, ingredient and recipe (Section 3), and formalize some of the around 50 operations
currently implemented in ASP Chef (Section 4). Finally, a couple of examples are provided in
Section 6, related work is discussed in Section 7, and concluding remarks and future works are
given in Section 8.</p>
    </sec>
    <sec id="sec-2">
      <title>2. Background</title>
      <p>We assume that the reader is familiar with the language of ASP [6], and only introduce the
background notions to which ASP practitioners may be less accustomed.</p>
      <p>Let Base64 be the function associating every binary string with a longer binary string that
can be interpreted as printable ASCII characters; the output string is obtained according to
RFC 4648 §4 (https://datatracker.ietf.org/doc/html/rfc4648#section-4). Let Base64 − 1 be the
inverse function of Base64 .</p>
      <sec id="sec-2-1">
        <title>Example 1. Let  be the following two-lines text:</title>
        <p>hello world
1 2 3
Base64 () is (the binary string associated with) the ASCII string aGVsbG8gd29ybGQKMSAyIDM=.
The two-lines text  can be obtained by applying Base64 − 1 to aGVsbG8gd29ybGQKMSAyIDM=.</p>
        <p>In the following the term object refers to any finite element of a fixed universe (comprising,
among other elements, strings, numbers, graphs, atoms, programs, and sequences). The notation
(1, . . . , ) is used to refer to a (finite) sequence of  ≥ 0 objects, where each object  is
associated with index . Moreover, by space we refer to a (possibly infinite) set of objects. Finally,
the Boolean values are denoted by T and F.</p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>3. ASP Recipes</title>
      <p>Terms are defined as usual by inductively combining constants and functions of positive arity;
similarly, atoms combine predicates and terms. An interpretation is a (finite) sequence of distinct
atoms, that is, an interpretation is a set of atoms also associating each atom with an index
(starting from 1); among the interpretations we include the inconsistent interpretation ⊥ to
represent errors. Let ℐ be the set of all sequences of interpretations.</p>
      <p>Example 2. ℐ includes, among others, the sequence ((hello), (hello), (hello, world )) of
interpretations. Note that atoms within the same interpretation must be distinct, while the same
interpretation may occur multiple times. Here, the last interpretation has index 3, and in that
interpretation atom hello has index 1 and atom world has index 2.</p>
      <p>An operation  is a function with signature  : ℐ →− ℐ , that is, a function receiving in
input a sequence of interpretations and producing in output a sequence of interpretations.
Example 3. Let Idx be the operation associating every atom in input with its index in the
interpretation it occurs. More formally, if the input contains an interpretation with index  and
atom  occurs at index  in that interpretation, then the output contains an interpretation with
index  and atom index (,  ) at index  in this interpretation.</p>
      <p>An operation  with side output space  is a function with signature  : ℐ →− ℐ ×  . No
particular restriction is imposed to the side output space; common cases include the set of
strings, the set of graphs, and the set containing the empty set (to essentially have operations
with no side output as a special case); to lighten the notation, if the side output space is {∅}, we
simply omit it. Let |ℐ denote the operation obtained from  by discarding the side output.
Example 4. Let Table be the operation reproducing in output its input, and additionally having
as side output a sequence of tables, one for each interpretation in input, each one containing a
row for each atom in the interpretation and columns for predicates and arguments of atoms.
Note that Table|ℐ is essentially a NOP (an operation that does nothing).</p>
      <p>A parameterized operation  with parameter space  and side output space  is a function
with signature  →− (ℐ →− ℐ ×  ), that is, ⟨ ⟩ is an operation with side output space 
for each parameter value  ∈  (note that angle brackets are used to denote a parameterized
operation instantiation). No particular restriction is imposed to the parameter space; common
cases include the set of integers, the set of strings, sets of tuples, and the set containing the
empty set (to have non-parameterized operations as a special case); to lighten the notation, if
the parameter space is {∅}, we simply omit it.</p>
      <p>Example 5. Let Index be the function associating every predicate name  with the following
operation: if the input contains an interpretation with index  and atom  occurs at index  in
that interpretation, then the output contains an interpretation with index  and atom p(,  ) at
index  in this interpretation. Note that Index ⟨index ⟩ is the operation Idx from Example 3.</p>
      <p>An ingredient is an instantiation of a parameterized operation with side output, that is,
if  is a parameterized operation with parameter space  and side output space , and
 ∈  is a parameter value, then ⟨ ⟩ is an ingredient. A recipe is a tuple of the form
(encode, Ingredients, decode), where Ingredients is a (finite) sequence of ingredients, and
encode and decode are Boolean values. Intuitively, the input of a recipe is either (the string
representation of) a sequence of interpretations in ℐ, or a string to be Base64 -encoded. The
input is processed by the pipeline of ingredients, possibly producing some side output along the
way. Finally, some encoded content is possibly decoded. Such an intuition is formalized below.</p>
      <p>Let Ingredients comprise  ≥ 0 ingredients 1⟨1⟩, . . . , ⟨⟩, and let in be the string
in input. The output and side output of the recipe (encode, Ingredients, decode) given in are
respectively out and 1, . . . ,  defined as follows:
• 0 is one of (i) ((__base64__(""))), if encode is true, where  = Base64 (in ); (ii) the
sequence of interpretations represented by in , where interpretations are separated by
the reserved character § and atoms are represented as facts, if in conforms to this
specification; (iii) (⊥) otherwise, to report an error.
• For each  = 1, . . . , , let  be ⟨⟩|ℐ(− 1), and  be the side output of ⟨⟩(− 1).</p>
      <p>Essentially, each ingredient of the recipe receives a sequence of interpretations from the
previous computational step, and produces in output a sequence of interpretations for
the next computational step. Possibly, a side output is also produced.
• Let out be the string obtained by concatenating the atoms of  represented as facts, one
per line, and using § as the separator for interpretations. If decode is true, out is further
processed by replacing every occurrence of __base64__("s") with (the ASCII string
associated with) Base64 − 1(); in this case, if Base64 − 1() produces an error, then 
is simply the string representation of (⊥).</p>
      <p>Let (in ) = (out , 1, . . . , ) denote the fact that out and 1, . . . ,  are the output and
side output of a recipe  given an input string in .</p>
      <p>Example 6. Recall  from Example 1, its Base64-encoding aGVsbG8gd29ybGQKMSAyIDM=,
and the operations Table and Index defined in Examples 4–5. Let 1, 2 be the recipes
(T, (Table), T) and (F, (Table, Index ⟨idx ⟩), T). Hence, 1() = (, (table1)), where table1
has one row with two cells, namely __base64__ and "aGVsbG8gd29ybGQKMSAyIDM=". In fact,
 is first encoded, produced as table1, and finally decoded back to . Similarly, for ′, ′′
being the strings __base64__("aGVsbG8gd29ybGQKMSAyIDM="). and idx(1,__base64__("
aGVsbG8gd29ybGQKMSAyIDM="))., it can be checked that 2(′) = (′′, (table1), ∅).</p>
    </sec>
    <sec id="sec-4">
      <title>4. Core Operations</title>
      <p>This section introduces some operations by specifying how they process input. Parameter
spaces are usually intuitive and parameter values that do not influence the output are possibly
denoted with an underscore. Regarding side output spaces, if not stated otherwise, they are
assumed to be {∅}; empty side output is also usually omitted.</p>
      <sec id="sec-4-1">
        <title>4.1. Searching</title>
        <p>Let SearchModels⟨decode_predicate, echo, rules, number _of _models⟩ be the operation
mapping (1, . . . , ) to (1,1, . . . , 1,1, 2,1, . . . , ,), where each ,1, . . . , , is obtained by
enumerating up to number _of _models answer sets of the program rules ∪ {Base64 − 1() |
decode_predicate(“”) ∈ } ∪ {(). | () ∈ ,  ̸= decode_predicate or echo = T}. As a
special case, number _of _models = 0 is used to enumerate all answer sets.</p>
        <sec id="sec-4-1-1">
          <title>Example 7. Let in be the fact</title>
          <p>hello.
rules1 : {world}.</p>
          <p>rules2 : wonderful. world.</p>
        </sec>
        <sec id="sec-4-1-2">
          <title>Hence, (in ) is the following text:</title>
          <p>and  be the recipe (F, (SearchModels(_, _, rules1, 0), (SearchModels(_, _, rules2, 0)), F),
where</p>
          <p>Note that after the application of the first ingredient there are essentially two answer sets,
namely {hello} and {hello, world}. Each of them is processed by the second ingredient,
which adds the facts wonderful and world.</p>
          <p>Let Optimize be an operation with the same parameter space and behavior of SearchModels,
but enumerating optimal answer sets (according to the objective function given in terms of
weak constraints, as usual in ASP).</p>
        </sec>
      </sec>
      <sec id="sec-4-2">
        <title>4.2. Sorting and Removing Duplicates</title>
        <p>Example 7 highlights that the order of interpretations and of atoms within them is not in general
under the control of all operations. In fact, the enumeration of answer sets does not follow a
specific order, and atoms within an answer set have no fixed order. Control over the order of
interpretations can be imposed by adding ingredients conceived for this purpose.</p>
        <p>Let SortCanonical be the operation sorting atoms within each interpretation
according to their lexicographical ordering (predicate first, then the first argument, and so on).
The ordering of terms gives priority to number, then to constants, finally to functions.
Let SortByPredicateOrArgument ⟨index , desc⟩ be the operation sorting atoms in each
interpretation according to their predicates (if index = 0) or their index -th arguments (if
index ̸= 0). The ordering is descending if desc = T, and ascending otherwise. Let
SortModelsCanonically ⟨excluded _predicates⟩ be the operation sorting the interpretations
according to their string representation, obtained after removing all instances of predicates in
excluded _predicates. Let Unique⟨excluded _predicates⟩ be the operation producing in output
the first interpretation in input, and every other interpretation that is not immediately preceded
by a copy of itself, once all instances of predicates in excluded _predicates are removed; often
this operation is preceded by a sort operation to remove all duplicates from the input.
Example 8. If  in Example 7 is extended with SortCanonical , the output will contain two
copies of the first interpretation. If  is further extended with SortModelsCanonically ⟨∅⟩ and
Unique⟨∅⟩, the output will contain only one copy of the first interpretation.</p>
      </sec>
      <sec id="sec-4-3">
        <title>4.3. Filtering and Selecting</title>
        <p>Let Filter ⟨regex ⟩ be the operation preserving only atoms whose string
representation matches the given regular expression regex , in each interpretation in input. Let
SelectPredicates⟨predicates⟩ be the operation preserving only instances of predicates in the
set predicates, for each interpretation in input. Let SelectModel ⟨index ⟩ be the operation
preserving only the index -th interpreation in input.</p>
      </sec>
      <sec id="sec-4-4">
        <title>4.4. Merging and Splitting</title>
        <p>Let Merge⟨predicate⟩ be the operation mapping (1, . . . , ) to the interpretation containing
an atom predicate() for each  = 1, . . . ,  and an atom predicate(,  ) for each  ∈ . Let
Split ⟨predicate⟩ be the operation replacing every interpretation in input with the interpretations
encoded by instances of predicate, according to the schema defined by Merge; that is, in each
model  in input, each predicate() ∈  leads to one model in output comprising  for each
predicate(,  ) ∈ .</p>
      </sec>
      <sec id="sec-4-5">
        <title>4.5. Closures and Encoded Content</title>
        <p>Let SymmetricClosure⟨input _predicate, closure_predicate, encode_predicate⟩ be the
operation extending each interpretation in input with the rules
closure_predicate(X,Y) :- input_predicate(X,Y).
closure_predicate(X,Y) :- input_predicate(Y,X).</p>
        <p>Actually, interpretations in input are extended with the atom encode_predicate(), where  is
the Base64-encoding of the above rules.</p>
        <p>Example 9. Let  be the recipe (F, (SymmetricClosure⟨link, link, b64⟩,
SearchModels⟨b64, F, ∅, 1⟩), F). Let in be link(a,b). Hence, (in ) produces in
output the interpretation consisting of link(a,b) and link(b,a).</p>
        <p>Similarly, TransitiveClosure extends interpretations in input with the rules
closure_predicate(X,Y) :- input_predicate(X,Y).
closure_predicate(X,Z) :- closure_predicate(X,Y), input_predicate(Y,Z).
Finally, an arbitrary content can be Base64-encoded by Base64 ⟨encode_predicate, content⟩.</p>
      </sec>
      <sec id="sec-4-6">
        <title>4.6. Working with Comma Separated Values</title>
        <p>Let ParseCSV ⟨decode_predicate, echo, separator , output _predicate⟩ be the operation
extending each interpretation  in input with atoms representing a CSV content Base64 − 1(),
for each decode_predicate(“”) ∈ . Each value occurring in cell (row , col ) in the
CSV content is represented by an atom of the form output _predicate(row , col , value).
The instances of decode_predicate are removed from the output if echo = F, and
the separator used by CSV can be specified (e.g., TAB, SPACE, or a string). Let
GenerateCSV ⟨input _predicate, echo, encode_predicate, separator ⟩ be the operation
producing a CSV content from instances of input _predicate in input, following the schema used by
ParseCSV . The CSV content is Base64-encoded and stored as an instance of encode_predicate.
Instances of input _predicate are removed from the output if echo = F, and the separator to
use in the CSV content can be specified.</p>
        <p>
          Example 10. Let  be the two-lines text from Example 1. Let  be the recipe
(T, (ParseCSV ⟨__base64__, F, SPACE, cell⟩), F). Hence, () produces in output the
interpretation consisting of the following facts:
cell(1, 1, "hello"). cell(1, 2, "world").
cell(
          <xref ref-type="bibr" rid="ref1 ref1 ref2">2, 1, 1</xref>
          ). cell(
          <xref ref-type="bibr" rid="ref2 ref2 ref2">2, 2, 2</xref>
          ).
        </p>
        <p>
          cell(
          <xref ref-type="bibr" rid="ref2 ref3 ref3">2, 3, 3</xref>
          ).
g(node(
          <xref ref-type="bibr" rid="ref1">1</xref>
          ),color(green),label(
          <xref ref-type="bibr" rid="ref1">1</xref>
          )).
g(node(
          <xref ref-type="bibr" rid="ref2">2</xref>
          ),color(blue),label(
          <xref ref-type="bibr" rid="ref2">2</xref>
          )).
g(node(
          <xref ref-type="bibr" rid="ref3">3</xref>
          ),color(red),label(
          <xref ref-type="bibr" rid="ref3">3</xref>
          )).
g(link(
          <xref ref-type="bibr" rid="ref1 ref2">1,2</xref>
          )).
g(link(
          <xref ref-type="bibr" rid="ref1 ref3">1,3</xref>
          )).
g(link(
          <xref ref-type="bibr" rid="ref2 ref3">2,3</xref>
          )).
        </p>
        <p>g(defaults,undirected).</p>
      </sec>
      <sec id="sec-4-7">
        <title>4.7. Visualizing Side Output</title>
        <p>Let Table be the operation forwarding its input and having as side output a sequence of tables,
as described in Example 4. Let Output be the operation forwarding its input and having as side
output its input. Let OutputEncodedContent ⟨predicate, echo⟩ be the operation forwarding its
input, possibly after removing instances of predicate if echo = F, and having as side output
the Base64-decoded content of all instances of predicate.</p>
        <p>Let Graph⟨predicate, echo⟩ be the operation forwarding its input, possibly after removing
instances of predicate if echo = F, and having as side output a graph described by instances of
predicate. The first argument of such instances is one of node(ID), link(SOURCE,TARGET) and
defaults. The other arguments have the form property(VALUE ). Node properties include
color, label, fx, fy, radius, and shape. Link properties include color, label, directed, and
undirected. Default properties include node_color, node_radius, node_shape, link_color,
directed, and undirected.</p>
        <p>Example 11. For an undirected graph encoded by predicate link and one of its -coloring
encoded by predicate assign, the following program can be used to obtain the facts shown in
Figure 4 (right):
g(defaults, undirected).
g(node(X), color(C), label(X)) :- assign(X,C).</p>
        <p>g(link(X,Y)) :- link(X,Y).</p>
        <p>The above program can be used as a parameter for SearchModels, and the graph shown in
Figure 4 (left) can be obtained by adding the ingredient Graph⟨g, F⟩.</p>
      </sec>
    </sec>
    <sec id="sec-5">
      <title>5. Implementation</title>
      <p>The notion of ASP recipe is put in practice by ASP Chef, a web app powered by the JavaScript
framework Svelte (https://svelte.dev/) and by the ASP engine clingo-wasm (https://github.
com/domoritz/clingo-wasm), a WebAssembly version of clingo [7]. ASP Chef is freely available
at https://asp-chef.alviano.net/, and its source code can be downloaded from https://github.com/
alviano/asp-chef. The only requirement is a modern browser (Firefox is recommended).</p>
      <p>Among the most interesting features of ASP Chef there is the representation of the recipe and
its input in the URL as a zipped JSON object. Such an object is placed in the hash fragment (the
portion following the character #) so that it is not transmitted to the server. In fact, once ASP
Chef is loaded in the browser, there is no further interaction with the server, which guarantees
that the server cannot essentially be overloaded, and also ensures that any sensitive data used
by programmers remains confidential .</p>
      <p>Regarding the user interface of ASP Chef, it is inspired by CyberChef (https://github.com/
gchq/CyberChef), a web app for encryption, encoding, compression and data analysis. As such,
it splits the window in three columns, placing all operations on the left pane, input and output
on the right pane, and the recipe in the middle pane; see Figure 5. Operations can be added
to the recipe with their default parameter values, and diferent parameter values can be given
in the recipe itself. Ingredients can be hidden, skipped, set as a termination point, as well as
moved up and down in the recipe. A brief description of each operation is shown as a tool-tip
to smooth out the learning curve.</p>
      <p>Another interesting feature of ASP Chef is its caching mechanism. Ingredients are applied
whenever the programmer changes something, taking advantage of the reactivity of SvelteKit.
However, ASP Chef is designed so that information flows only in one direction, namely from the
input to the first ingredient, and then from each ingredient to the next until the final output is
produced. Such a design choice enables a simple, yet powerful caching strategy: if an ingredient
in the recipe is changed, the output and side output of all ingredients occurring before it are
1 in_path(M,T) :- model(M, in_path(T)).
2 town(T) :- model(M, town(T)).
3 connected(X,Y) :- model(_, connected(X,Y)).
4 g(node(T), label(T)) :- town(T).
5 g(node(T), color(red)) :- select(T).
6 g(link(X,Y), undirected) :- connected(X,Y), X &lt; Y.
16 btn(X,Y,C,S) :- btn(X,Y,C,S-1), step(S), not cut(X,Y,S).
17 :- btn(_,_,_,S), not step(S+1).
18 cell(1,1,S) :- S = #count{A,B,T : pair(A,B,T)}.
19 cell(T+1,1,X ) :- pair((X,Y), (X',Y'), T).
20 cell(T+1,2,Y ) :- pair((X,Y), (X',Y'), T).
21 cell(T+1,3,X') :- pair((X,Y), (X',Y'), T).
22 cell(T+1,4,Y') :- pair((X,Y), (X',Y'), T).
those previously computed and recoverable from the cache.</p>
      <p>Finally, ASP Chef takes inspiration from initial learning environments like Scratch [8] and
low-code development platforms [9] like Appian (https://appian.com/), which are essentially easy
to use visual environments for defining possibly complex procedures in terms of components
and their interactions. Within this respect, ASP Chef provides ingredients as the analogous
of components, and their interactions are simplified to the extreme in a single-direction linear
lfow as done by CyberChef. All in all, a programmer is expected to write less code to define an
ASP recipe than an equivalent pipeline in a general purpose programming language, even if the
amount of ASP code to write in ASP recipes is not necessarily low.</p>
    </sec>
    <sec id="sec-6">
      <title>6. Use Cases</title>
      <p>Let us consider Fighting with the gang of Billy the Kid from Section 1, and the input in shown
in Figure 1 (right). Below are the ingredients of an ASP recipe addressing this problem.</p>
      <p>1. SymmetricClosure⟨connected, connected, b64⟩, to introduce the rules enforcing the
symmetric closure of connected, since the graph is undirected.
2. SearchModels⟨b64, F, Figure 3 (left), 0⟩, to enumerate all paths of interest.
3. SortCanonical , SortModelsCanonically ⟨{path}⟩, and Unique⟨{path}⟩, to remove
paths associated with the same set of towns.
4. Merge⟨model⟩, and SearchModels⟨_, _, Figure 6 (lines 1–3), 1⟩, to pack all paths in a
single interpretation. Note that paths are assigned an identifier, which is the index of the
interpretation they occur in the input sequence of Merge.
5. Optimize⟨_, _, Figure 3 (right), 1⟩, to solve the combinatorial optimization subtask.
6. SearchModels⟨_, _, Figure 6 (lines 4–6), 1⟩, and Graph⟨g, F⟩, to show a graph.
A slightly extended recipe was used to obtain the screenshot shown in Figure 5.</p>
      <p>Let us consider Buttons and Scissors from LP/CP Programming Contest: a grid of buttons of
diferent colors is given, and the goal is to detach all buttons with a sequence of straight cuts
involving buttons of the same color. The input is given in CSV, and the output is expected in
CSV, so both encode and decode flags are set to true. The ingredients are given below.
1. ParseCSV ⟨__base64__, F, SPACE, c⟩, and SearchModels⟨_, _, Figure 7 (lines 1–3), 1⟩,
to accommodate the input in a format suitable for ASP.
2. SearchModels⟨_, _, Figure 7 (lines 4–17), 1⟩, to address the combinatorial search subtask
of the problem. Without going into too much details, the sequence of cuts is guessed and
the grid is updated after each cut, requiring to have no buttons after the last cut.
3. SearchModels⟨_, _, Figure 7 (lines 18–22), 1⟩, to represent a CSV output: the first line is
the number of cuts, and the other lines give the coordinates of the starting and ending
point of each cut.</p>
      <p>The above recipe can be extended to produce the graph shown in Figure 8, where nodes are
given fixed positions by using the properties fx and fy. Figure 8 also shows a graph visualization
for another problem from LP/CP Programming Contest, where node labels use emoji to represent
walls (red squares) around points of interest (integers) and attacked cells (swords).</p>
    </sec>
    <sec id="sec-7">
      <title>7. Related Work</title>
      <p>Tools supporting the development of ASP programs were presented by many other works in
the literature. Many of them focused on the design of Integrated Development Environment
(IDE), like ASPIDE [10], SeaLion [11], and LoIDE [12]. While ASPIDE and SeaLion are desktop
applications, LoIDE is designed as a web application. Comparing to ASP Chef, which is not
intended to be an IDE, LoIDE requires a backend server to complete ASP computational tasks,
while ASP Chef can run everything in the browser thanks to clingo-wasm. Other works dealt
with simplifying the development of ASP modules and microservices [13, 14, 15, 16, 17], and
share with ASP Chef the goal of employing ASP in a non-monolithic way.</p>
      <p>Visualization of ASP output was approached by many other works in the literature. Among
them, there are ASPViz [18], IDPD3 [19] and Kara [20], which are all based on the use of several
predicates to describe how to draw a graphical representation of the solution provided by an
answer set solver. The idea of easing the declarative specification of a graphical representation
for ASP was revived in an interesting teaching experiment [21], which however is restricted to
problems dealing with grids like Sudoku. On the same spirit, the more recent clingraph [22]
can produce high-quality graphs and images that can be exported in LATEX.</p>
      <p>These works are related to the Graph operation introduced in Section 4.7, which is also
capable of producing a graphical representation by interpreting instances of one user-specified
predicate. At its current state, the Graph operation does not reach the richness of other
visualization tools for ASP, as for example it does not support the creation of animations. On
the other hand, ASP Chef is ready to use in the browser, without any additional software, and
the Graph operation produces interactive graphs with the possibility to search and highlight
node and link labels. Moreover, being a side output, the Graph operation can be introduced in
all points of interest within the same recipe, showing intermediate states of the pipeline.</p>
    </sec>
    <sec id="sec-8">
      <title>8. Conclusion</title>
      <p>ASP recipes aim at easing the development of broad pipelines involving ASP. Uniformity of input
and output format enables arbitrary combinations of operations, actually without limiting too
much the data that can be manipulated in the pipeline thanks to the support for Base64 content.
ASP Chef provides a ready-to-use framework to practice with ASP recipes, and employs the
ASP engine clingo-wasm not only to address combinatorial search and optimization, but also
to implement several operations.</p>
      <p>The extensible design of ASP Chef leaves space for future work. First of all, there are several
other operations that are already implemented in ASP Chef and have not being formalized here.
Some of them possibly require a more sophisticated notion of recipe, as for example Store and
Restore operations, which require a notion of state. Moreover, the need for new operations is
expected to arise from diferent domains, as for example we are experiencing in the definition
of cyber ranges for digital twins defined in the Digital Twin Definition Language [23].</p>
      <p>Finally, even if eficiency of computation is not the main goal of ASP Chef, an empirical
assessment is expected in the near future, to better understand the overhead due to running the
ASP engine in the browser. We do not expect a too severe overhead, but anyhow we already
implemented a Server operation that can lighten the computation addressed by the browser.</p>
    </sec>
    <sec id="sec-9">
      <title>Acknowledgments</title>
      <p>This work was partially supported by Italian Ministry of Research (MUR) under PNRR project
FAIR “Future AI Research”, CUP H23C22000860006, under PNRR project Tech4You “Technologies
for climate change adaptation and quality of life improvement”, CUP H23C22000370006, and
under PNRR project SERICS “SEcurity and RIghts in the CyberSpace”, CUP H73C22000880001;
by Italian Ministry of Health (MSAL) under POS project RADIOAMICA, CUP H53C22000650006;
by the LAIA lab (part of the SILA labs) and by GNCS-INdAM.
[11] P. Busoniu, J. Oetsch, J. Pührer, P. Skocovsky, H. Tompits, Sealion: An eclipse-based IDE for
answer-set programming with advanced debugging support, Theory Pract. Log. Program.
13 (2013) 657–673.
[12] F. Calimeri, S. Germano, E. Palermiti, K. Reale, F. Ricca, Developing ASP programs with</p>
      <p>ASPIDE and LoIDE, Künstliche Intell. 32 (2018) 185–186.
[13] F. Calimeri, G. Ianni, Template programs for disjunctive logic programming: An operational
semantics, AI Commun. 19 (2006) 193–206.
[14] S. Costantini, G. D. Gasperis, Dynamic goal decomposition and planning in MAS for
highly changing environments, in: CILC, volume 2214 of CEUR Workshop Proceedings,
CEUR-WS.org, 2018, pp. 40–54.
[15] P. Cabalar, J. Fandinno, Y. Lierler, Modular answer set programming as a formal
specification language, Theory Pract. Log. Program. 20 (2020) 767–782.
[16] S. Costantini, G. D. Gasperis, L. D. Lauretis, An application of declarative languages in
distributed architectures: ASP and DALI microservices, Int. J. Interact. Multim. Artif. Intell.
6 (2021) 66–78.
[17] P. Cabalar, J. Fandinno, T. Schaub, P. Wanko, On the semantics of hybrid ASP systems
based on clingo, Algorithms 16 (2023) 185.
[18] O. Clife, M. D. Vos, M. Brain, J. A. Padget, ASPVIZ: declarative visualisation and animation
using answer set programming, in: ICLP, volume 5366 of Lecture Notes in Computer Science,
Springer, 2008, pp. 724–728.
[19] R. Lapauw, I. Dasseville, M. Denecker, Visualising interactive inferences with IDPD3,</p>
      <p>CoRR abs/1511.00928 (2015).
[20] C. Kloimüllner, J. Oetsch, J. Pührer, H. Tompits, Kara: A system for visualising and visual
editing of interpretations for answer-set programs, in: INAP/WLP, volume 7773 of Lecture
Notes in Computer Science, Springer, 2011, pp. 325–344.
[21] A. Dovier, P. Benoli, M. C. Brocato, L. Dereani, F. Tabacco, Reasoning in high schools: Do
it with ASP!, in: CILC, volume 1645 of CEUR Workshop Proceedings, CEUR-WS.org, 2016,
pp. 205–213.
[22] S. Hahn, O. Sabuncu, T. Schaub, T. Stolzmann, Clingraph: ASP-based visualization, in:</p>
      <p>LPNMR, volume 13416 of Lecture Notes in Computer Science, Springer, 2022, pp. 401–414.
[23] M. Platenius-Mohr, S. Malakuti, S. Grüner, J. Schmitt, T. Goldschmidt, File- and API-based
interoperability of digital twins by model transformation: An IIoT case study using asset
administration shell, Future Gener. Comput. Syst. 113 (2020) 94–105.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>M.</given-names>
            <surname>Balduccini</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Barborak</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D. A.</given-names>
            <surname>Ferrucci</surname>
          </string-name>
          ,
          <article-title>Pushing the limits of clingo's incremental grounding and solving capabilities in practical applications</article-title>
          ,
          <source>Algorithms</source>
          <volume>16</volume>
          (
          <year>2023</year>
          )
          <fpage>169</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>V.</given-names>
            <surname>Lifschitz</surname>
          </string-name>
          , Answer Set Programming, Springer,
          <year>2019</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>E.</given-names>
            <surname>Erdem</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Gelfond</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Leone</surname>
          </string-name>
          ,
          <article-title>Applications of answer set programming</article-title>
          ,
          <source>AI Mag</source>
          .
          <volume>37</volume>
          (
          <year>2016</year>
          )
          <fpage>53</fpage>
          -
          <lpage>68</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>M.</given-names>
            <surname>Alviano</surname>
          </string-name>
          ,
          <string-name>
            <given-names>W.</given-names>
            <surname>Faber</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Leone</surname>
          </string-name>
          ,
          <article-title>Disjunctive ASP with functions: Decidable queries and efective computation</article-title>
          ,
          <source>Theory Pract. Log. Program</source>
          .
          <volume>10</volume>
          (
          <year>2010</year>
          )
          <fpage>497</fpage>
          -
          <lpage>512</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>R.</given-names>
            <surname>Bertolucci</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Capitanelli</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Dodaro</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Leone</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Maratea</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Mastrogiovanni</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Vallati</surname>
          </string-name>
          ,
          <article-title>Manipulation of articulated objects using dual-arm robots via answer set programming</article-title>
          ,
          <source>Theory Pract. Log. Program</source>
          .
          <volume>21</volume>
          (
          <year>2021</year>
          )
          <fpage>372</fpage>
          -
          <lpage>401</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>F.</given-names>
            <surname>Calimeri</surname>
          </string-name>
          ,
          <string-name>
            <given-names>W.</given-names>
            <surname>Faber</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Gebser</surname>
          </string-name>
          , G. Ianni,
          <string-name>
            <given-names>R.</given-names>
            <surname>Kaminski</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Krennwallner</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Leone</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Maratea</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Ricca</surname>
          </string-name>
          , T. Schaub,
          <article-title>ASP-Core-2 input language format</article-title>
          ,
          <source>Theory Pract. Log. Program</source>
          .
          <volume>20</volume>
          (
          <year>2020</year>
          )
          <fpage>294</fpage>
          -
          <lpage>309</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>M.</given-names>
            <surname>Gebser</surname>
          </string-name>
          , B. Kaufmann, T. Schaub,
          <article-title>Conflict-driven answer set solving: From theory to practice, Artif</article-title>
          . Intell.
          <volume>187</volume>
          (
          <year>2012</year>
          )
          <fpage>52</fpage>
          -
          <lpage>89</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>J. H.</given-names>
            <surname>Maloney</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Resnick</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Rusk</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B.</given-names>
            <surname>Silverman</surname>
          </string-name>
          ,
          <string-name>
            <surname>E. Eastmond,</surname>
          </string-name>
          <article-title>The scratch programming language and environment</article-title>
          ,
          <source>ACM Trans. Comput. Educ</source>
          .
          <volume>10</volume>
          (
          <year>2010</year>
          )
          <volume>16</volume>
          :
          <fpage>1</fpage>
          -
          <lpage>16</lpage>
          :
          <fpage>15</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>A.</given-names>
            <surname>Sahay</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Indamutsa</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D. D.</given-names>
            <surname>Ruscio</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Pierantonio</surname>
          </string-name>
          ,
          <article-title>Supporting the understanding and comparison of low-code development platforms</article-title>
          , in: SEAA, IEEE,
          <year>2020</year>
          , pp.
          <fpage>171</fpage>
          -
          <lpage>178</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>O.</given-names>
            <surname>Febbraro</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K.</given-names>
            <surname>Reale</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Ricca</surname>
          </string-name>
          ,
          <article-title>ASPIDE: integrated development environment for answer set programming</article-title>
          ,
          <source>in: LPNMR</source>
          , volume
          <volume>6645</volume>
          of Lecture Notes in Computer Science, Springer,
          <year>2011</year>
          , pp.
          <fpage>317</fpage>
          -
          <lpage>330</lpage>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>