# Current status of s(CASP)

**URL:** <https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507>\
**Category:** Help!\
**Created:** [February 1, 2026, 12:48pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507 "2026-02-01T12:48:25Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![alanbur](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/alanbur/32/7166_2.png) [@alanbur](https://swi-prolog.discourse.group/u/alanbur)\
**Post date:** [February 1, 2026, 12:48pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/1 "2026-02-01T12:48:25Z")

</div>

I’m considering using the s(CASP) pack for rules-based fault diagnosis. However I’m wondering what the current status is - the docs seem kinda sparse, the only comprehensive ones I’ve been able to find are on the SWISH site at [https://swish.swi-prolog.org/pldoc/pack/sCASP/](https://swish.swi-prolog.org/pldoc/pack/sCASP/) and it looks like the main development is elsewhere? Also, many of the examples don’t seem to work any more?

I’ll be using it internally so it will be fine as long as it will keep working on future SWI versions.

Another question: In some of the examples I see things like this:

```prolog
#pred wounded_bird(X) :: '@(X) is a wounded bird'.
wounded_bird(john). % john is wounded

```

but I’ve not been able to find any documentation for what `#pred` does, nor for any of the similar-looking things such as `#abducible`, `#show` and so on. What do they do?

I’m also having problems calling out to Prolog from SCASP, the README says to use the prolog/1 predicate but I can’t get it to work:

```prolog
:- attach_packs(packs, [replace(true)]).
:- use_module(library(scasp)).
:- use_module(library(scasp/embed)).

is_even(X) :-
    0 is X mod 2.

:- begin_scasp(alan).

:- prolog (is_even/1) as opaque.

ok(X) :-
    candidate(X),
    is_even(X).  

candidate(1).
candidate(2).
candidate(3).

:- end_scasp.

```

Results in:

```prolog
Warning: scasp.pl:20:
Warning: scasp_predicate `(prolog)/1' does not exist
Warning: scasp.pl:20:
Warning: scasp_predicate `is_even/1' does not exist

```

Thanks.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [February 1, 2026, 3:21pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/2 "2026-02-01T15:21:43Z")

</div>

> [@alanbur](#):
>
> and it looks like the main development is elsewhere?

sCASP is primarily created by Joaquin Arias for Ciao Prolog. The SWI-Prolog implementation is is a port with some enhancements. It performs a lot better, it allows for embedding sCASP programs in Prolog programs and with some limitations the other way around and it extends the `#pred` directives. It is all not very well documented indeed ☹

> [@alanbur](#):
>
> `#pred`

Allows you to associate a natural language expression with the fact that some predicate is true. The SWI-Prolog implementation extends that to the HTML generator, so you can generate dedicated HTML for the justification tree.

> [@alanbur](#):
>
> #abducible

creates a negative cycle that creates two possible worlds: one where the predicate is true and one where it is false.

> [@alanbur](#):
>
> `#show`

Tells the system to include only the given predicates into the displayed model rather than all predicates.

> [@alanbur](#):
>
> `:- begin_scasp(alan).`

That is old school. Just write normal Prolog code for things you want executed as sCASP (respecting the limitations of sCASP) and call scasp/2 or ?/1 with the various variations that dictate what is being displayed. Quite likely begin\_scasp does not work any more.

As is, sCASP has a steep learning curve ☹

---

<div class="post-metadata">

**Author:** ![alanbur](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/alanbur/32/7166_2.png) [@alanbur](https://swi-prolog.discourse.group/u/alanbur)\
**Post date:** [February 1, 2026, 9:35pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/4 "2026-02-01T21:35:31Z")

</div>

> [@jan](#):
>
> It is all not very well documented indeed ☹

As the SWI version is a port I’ve had a look at the Ciao docs to see if they helped, unless I’m missing something that’s not very well documented either, ☹

> [@jan](#):
>
> Allows you to associate a natural language expression with the fact that some predicate is true

Thanks, that was my guess, I’m not sure I really grok the syntax though.

> [@jan](#):
>
> That is old school. Just write normal Prolog code for things you want executed as sCASP … Quite likely begin\_scasp does not work any more.

Ah, that perhaps explains why some of the examples are broken as they still use it.

> [@jan](#):
>
> As is, sCASP has a steep learning curve ☹

It looked interesting because you get explanations “for free”, but it sounds like it’s only a toy, and the lack of working examples and documentation, and some documentation that’s just plain wrong, is a killer. Shame.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [February 2, 2026, 8:20am UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/5 "2026-02-02T08:20:53Z")

</div>

> [@alanbur](#):
>
> but it sounds like it’s only a toy, and the lack of working examples and documentation, and some documentation that’s just plain wrong, is a killer. Shame.

It is more than a toy, but less than what one should expect. To get started, load a program, e.g.

```prolog
:- use_module(library(scasp)).

opera(D) :- not home(D).
home(D):- not opera(D).
home(monday).

false :- baby(D), opera(D).

baby(tuesday).

```

Load this into SWI-Prolog. Now you can do e.g.

```prolog
108 ?- ? opera(D).
% s(CASP) model
{ not baby(_A), not home(D), opera(D),
  baby(tuesday), home(tuesday), not opera(tuesday)
},
D ∉ [monday,tuesday],
_A ∉ [tuesday] 

```

Or, for access from a program

```prolog
107 ?- scasp(opera(D), [model(M), tree(T)]).
M = [not baby(_A), baby(tuesday), not home(D), home(tuesday), opera(D), not opera(tuesday)],
T = query-[goal_origin(opera(D), <clause>(0x4769b90))-[(not home(D))-[chs(opera(D))-[]]], o_nmr_check-[(not o_chk_1)-[(not baby(…))-[], goal_origin(…, …)-[], … - …]]],
D ∉ [monday,tuesday],
_A ∉ [tuesday] .

```

This allows you to reason about the model or justification tree.

---

<div class="post-metadata">

**Author:** ![alanbur](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/alanbur/32/7166_2.png) [@alanbur](https://swi-prolog.discourse.group/u/alanbur)\
**Post date:** [February 2, 2026, 12:04pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/6 "2026-02-02T12:04:15Z")

</div>

Thank you 🙂 I did manage to get the bird / penguin example working after my earlier post, pretty much exactly along the lines you describe. My next step will be to investigate performance - I have around 25k “symptom” facts that I need to reason across.

---

<div class="post-metadata">

**Author:** ![herme](https://avatars.discourse-cdn.com/v4/letter/h/74df32/32.png) [@herme](https://swi-prolog.discourse.group/u/herme)\
**Post date:** [February 2, 2026, 12:30pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/7 "2026-02-02T12:30:02Z")

</div>

In case it helps, there is a manual in Joaquin’s [sCASP repo](https://gitlab.software.imdea.org/ciao-lang/sCASP) (a separate Ciao Prolog bundle).

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [February 2, 2026, 12:34pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/8 "2026-02-02T12:34:53Z")

</div>

> [@alanbur](#):
>
> My next step will be to investigate performance - I have around 25k “symptom” facts that I need to reason across.

Often not that good, though it depends more on the structure of the rules than the number of them. In general, sCASP is interesting if you have complicated negation and you need stable model semantics for this. It also deals with uncertainty in the sense of “I know this is true”, “I know this is false” or “I don’t know”. That can be modelled more lightweight in Prolog without sCASP, but you get it in the package.

sCASP explanation is a mere proof tree. It is easy enough to add that to Prolog. Explanation with tabling is a little harder.

The first question to ask is what kind of reasoning do you need? Now and in the future of your project.

Another way to look at these choices is to see whether you can model your data in the limited language sCASP offers. If yes, do so. You can then decide to execute the program under sCASP, plain Prolog or Prolog with tabling. Using a simple declarative specification allows for a lot of automated checking/rewriting/execution/…

---

<div class="post-metadata">

**Author:** ![alanbur](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/alanbur/32/7166_2.png) [@alanbur](https://swi-prolog.discourse.group/u/alanbur)\
**Post date:** [February 2, 2026, 1:20pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/9 "2026-02-02T13:20:19Z")

</div>

> [@jan](#):
>
> The first question to ask is what kind of reasoning do you need? Now and in the future of your project.

Exactly so, that’s the pondering I’m doing at the moment 🙂 I’m building the system in layers:

- Load a JSON snapshot of the state of a system and create a fact for each resource of interest in the JSON.
- Create “link” facts between the resource facts based on knowledge of the relationships between resources, e.g. “Resource Type A holds the UID of associated resource type B in this field”.
- Generic “symptom” rules, e.g. “If resource A has a reference to resource B, and B no longer exists, A is probably an orphan”
- Resource-type specific “symptom” rules, e.g. “If this resource has been in this state for more than X hours, it’s broken” or “If attribute A of a resource has this value, attribute B must be one of these values”.

I then group all the symptoms for a given resource together, so I can see all its “brokenness” in once place. There’s a TUI that allows filtering and display of the aggregated symptoms. Although the facts and symptoms are generated dynamically from the incoming JSON, they don’t change once loaded, so I make heavy use of tabling. Once the initial data load & analysis is done, display and querying is very fast.

At a higher level, the JSON data describes multiple instances of “Systems”, where each system is implemented using a collection of resources of different types. The number of instances of a resource in each system can vary, but the overall “shape” of a system in terms of the types of and relationships between resources is known, but will need to be modelled - TBD.

The next phase, for which I was considering s(CASP), is to use the symptoms and the TBD model of the systems to reason about faults at a higher level, e.g. “If you get this error and a system has these symptoms, here’s what’s probably broken, and here’s how to investigate further / fix it” or “I can see these symptoms, that’s going to cause this problem if you don’t fix it, here’s how to do so”. For that I could probably roll up the detailed symptoms into summaries, whilst I’d need to retain resource UIDs etc to identify exactly what needed looking at once a problem has been identified, the initial reasoning might be possible with just “There’s N cases of Symptom A in System B”.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [February 2, 2026, 1:44pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/10 "2026-02-02T13:44:35Z")

</div>

> [@alanbur](#):
>
> he number of instances of a resource in each system can vary, but the overall “shape” of a system in terms of the types of and relationships between resources is known, but will need to be modelled - TBD.

That where I would start. Just try to write down the rules, not worrying too much about how they will be executed. Just try to express the knowledge in (Prolog) syntax, inventing names for building blocks you need that match the domain. Then you have something any domain expert can read and write. Next, worry about how to turn this into something executable.

---

<div class="post-metadata">

**Author:** ![alanbur](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/alanbur/32/7166_2.png) [@alanbur](https://swi-prolog.discourse.group/u/alanbur)\
**Post date:** [June 19, 2026, 1:45pm UTC](https://swi-prolog.discourse.group/t/current-status-of-s-casp/9507/11 "2026-06-19T13:45:14Z")

</div>

I ended up not using a(CASP), the Prolog system determines the issues and groups them by resource. That’s fed into a LLM that does the grouping, ranking and corrective action suggestions. It works really well.
