<jupyter_start><jupyter_text>ASP solving with clingo in PythonThis is a small example to show how you can do Answer Set Programming with [clingo](https://potassco.org/clingo/) (part of the Potsdam Answer Set Solving Collection; or *Potassco*, for short) in Python.First, install clingo, e.g., using:`conda install -c potassco clingo`To use clingo in Python, import the clingo package.<jupyter_code>import clingo<jupyter_output><empty_output><jupyter_text>You can then write an answer set program as a string.For an explanation of the syntax of answer set programs (that clingo uses) and for examples, see Potassco's [Getting Started page](https://potassco.org/doc/start/) and their [guide](https://github.com/potassco/guide/releases/tag/v2.2.0).Let's take the following simple example.<jupyter_code>asp_program = """#const k=3.
number(1..k).
left(X) :- not right(X), number(X).
right(X) :- not left(X), number(X).
:- right(2).""";<jupyter_output><empty_output><jupyter_text>We then create a clingo Control object, load the answer set program, and do the grounding (compiling away variables).<jupyter_code>control = clingo.Control();
control.add("base", [], asp_program);
control.ground([("base", [])])<jupyter_output><empty_output><jupyter_text>Before we ask clingo to find models (answer sets) for our program, we define a function `on_model` that will be called for each model.For this example, we let this function just print the model.<jupyter_code>def on_model(model):
    for atom in model.symbols(atoms=True):
        print("Atom with name {} and arguments {} is true in the model: {}".format(atom.name, atom.arguments, atom));<jupyter_output><empty_output><jupyter_text>We then ask clingo to find a single model for our program, and to call `on_model` on this model when it is found.<jupyter_code>control.configuration.solve.models = 1; # use 0 if you want to find all models
answer = control.solve(on_model=on_model)<jupyter_output>Atom with name number and arguments [1] is true in the model: number(1)
Atom with name number and arguments [2] is true in the model: number(2)
Atom with name number and arguments [3] is true in the model: number(3)
Atom with name right and arguments [1] is true in the model: right(1)
Atom with name right and arguments [3] is true in the model: right(3)
Atom with name left and arguments [2] is true in the model: left(2)<jupyter_text>We can check whether `solve` found a model or not:<jupyter_code>if answer.satisfiable == True:
    print("Found a model!");
else:
    print("Did not find a model!");<jupyter_output>Found a model!
{'fraction_non_alphanumeric': 0.10959968907889624, 'fraction_numerical': 0.00777302759424796, 'mean_word_length': 5.5, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '21710', 'license': 'MIT', 'n_tokens_mistral': 818, 'n_tokens_neox': 801, 'n_words': 309, 'path': 'examples/asp.ipynb', 'repo_name': 'BalintHompot/SymbolicSystems', 'size': '2573'}