Problems with human explanations in s(CASP) when using abducibility

I think this is a feature request.

I’m using the latest version of SWI-Prolog with the sCASP library and accessing it through swiplserver. This is being used as the back-end reasoner for Blawx, which displays the human-language version of the explanation tree to the user.

Here’s what the human language explanation for one model looks like when I use abducibility on the rules for rock paper scissors, and ask how a game might be won.

the winner of anything is anything, because
      anything played in anything, because
         there is no evidence that o_player holds for anything, and anything, because
            it is assumed that anything played in anything
         abducible$ holds for player(_32,_34), because
            there is no evidence that abducible$$ holds for player(_32,_34), because
               abducible$ holds for player(_32,_34), because
                  it is assumed that there is no evidence that abducible$$ holds for player(_32,_34)
      anything played in anything, because
         there is no evidence that o_player holds for anything, and anything, because
            it is assumed that anything played in anything
         abducible$ holds for player(_32,_818), because
            there is no evidence that abducible$$ holds for player(_32,_818), because
               abducible$ holds for player(_32,_818), because
                  it is assumed that there is no evidence that abducible$$ holds for player(_32,_818)
      anything threw rock, because
         there is no evidence that o_throw holds for anything, and rock, because
            it is assumed that anything threw rock
         abducible$ holds for throw(_34,rock), because
            there is no evidence that abducible$$ holds for throw(_34,rock), because
               abducible$ holds for throw(_34,rock), because
                  it is assumed that there is no evidence that abducible$$ holds for throw(_34,rock)
      anything threw scissors, because
         there is no evidence that o_throw holds for anything, and scissors, because
            it is assumed that anything threw scissors
         abducible$ holds for throw(_818,scissors), because
            there is no evidence that abducible$$ holds for throw(_818,scissors), because
               abducible$ holds for throw(_818,scissors), because
                  it is assumed that there is no evidence that abducible$$ holds for throw(_818,scissors)
      rock beats scissors

That’s a lot of anything. It would be great if we could keep the original variable name in the query, when we have one, and use the skolem names. So Player _118 where the variable has a name and just _118 when it doesn’t.

It would also be great if the human versions of predicates were being used inside the abducibility statements.

It would also be great if the abducibility statements would use something natural-language-ish instead of “abducible$ holds for”.

It would also be great of o_predicate was translated into "it is not proven that " followed by the human language version of the positive predicate.

The Ciao implementation of s(CASP) deals with some of these things differently, but I forget which, and how, exactly.

Thanks very much.

Sorry for the late reaction. I’ve been traveling for work and a bit of holidays. Yes , there is still some work to do on the human explanations. Some of these may indeed be correctly handled by the Ciao version. The SWI-Prolog version uses a slightly different approach to the justification tree. Where the Ciao version goes directly from the raw justification to the final output, the SWI-Prolog version first creates a clean Prolog representation of the justification, then converts this into text or HTML using a DCG. Some details probably have been lost in this process :frowning:

AFAIK also Ciao looses track of the original variable names. It would be interesting to see whether we can preserve/recover these.

Could you share the program? It seems a nice example leading to a weird human explanation.

Hi @JasonMorris,
I’ve tried to reproduce the results posted above, but as for preserving variable names in my case I see that s(CASP) does preserve them in the justification tree (not in the query description though).

Here’s the program I’ve created to try and reproduce these results (I just tweaked your code from here based on the output provided above):

#pred player(G, X) :: '@(X) played in @(G)'.
#pred winner(Game,Player) :: 'The winner of @(Game) is @(Player)'.
#pred throw(Player,Sign) :: '@(Player) threw @(Sign)'.
#pred beat(Sign,OtherSign) :: '@(Sign) beats @(OtherSign)'.

beat(rock,scissors).
beat(scissors,paper).
beat(paper,rock).

#abducible player(Game, Player).
#abducible throw(Player, Sign).

winner(Game,Player) :-
  player(Game, Player),
  player(Game, OtherPlayer),
  throw(Player,Sign),
  throw(OtherPlayer,OtherSign),
  beat(Sign,OtherSign).

And here’s the output I get for the most general query:

$ ./scasp --query 'winner(Game, Player)' --human --tree examples/rps.pl
% Query
I would like to know if
   The winner of anything is anything?
% ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
%                                                 Answer 1 (0.002 sec)
% ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
% Justification
   The winner of Game is Player, because
      Player played in Game, because
         it is assumed that Player played in Game, and
         abducible holds for player(Game,Player), because
            abducible holds for player(Game,Player), because
               it is assumed that there is no evidence that o_abducible holds for player(Game,Player)
      A played in Game, because
         it is assumed that A played in Game, and
         abducible holds for player(Game,A), because
            abducible holds for player(Game,A), because
               it is assumed that there is no evidence that o_abducible holds for player(Game,A)
      Player threw rock, because
         it is assumed that Player threw rock, and
         abducible holds for throw(Player,rock), because
            abducible holds for throw(Player,rock), because
               it is assumed that there is no evidence that o_abducible holds for throw(Player,rock)
      A threw scissors, because
         it is assumed that A threw scissors, and
         abducible holds for throw(A,scissors), because
            abducible holds for throw(A,scissors), because
               it is assumed that there is no evidence that o_abducible holds for throw(A,scissors)
      rock beats scissors
   ∎

As you can see I can’t reproduce the whole lot of anythings just yet.

Is my contrived program close enough to what you ran?
Are you getting these results with the latest s(CASP) commit (f47d5c039bc219347a08aad8600951a3496ddad2)?

Cheers

It just came to me that if one runs the s(CASP) query from the Prolog top-level, then the names of the variables in the query will surely be lost.

Now I get the same output as you have with:

?- (? winner(Player, Game)), scasp_justification(Tree, []), human_justification_tree(Tree, []).
   The winner of anything is anything, because
      anything played in anything, because
         there is no evidence that o_player holds for anything, and anything, because
            it is assumed that anything played in anything
         abducible$ holds for player(_26,_28), because
            there is no evidence that abducible$$ holds for player(_26,_28), because
               abducible$ holds for player(_26,_28), because
                  it is assumed that there is no evidence that abducible$$ holds for player(_26,_28)
      anything played in anything, because
         there is no evidence that o_player holds for anything, and anything, because
            it is assumed that anything played in anything
         abducible$ holds for player(_26,_670), because
            there is no evidence that abducible$$ holds for player(_26,_670), because
               abducible$ holds for player(_26,_670), because
                  it is assumed that there is no evidence that abducible$$ holds for player(_26,_670)
      anything threw rock, because
         there is no evidence that o_throw holds for anything, and rock, because
            it is assumed that anything threw rock
         abducible$ holds for throw(_28,rock), because
            there is no evidence that abducible$$ holds for throw(_28,rock), because
               abducible$ holds for throw(_28,rock), because
                  it is assumed that there is no evidence that abducible$$ holds for throw(_28,rock)
      anything threw scissors, because
         there is no evidence that o_throw holds for anything, and scissors, because
            it is assumed that anything threw scissors
         abducible$ holds for throw(_670,scissors), because
            there is no evidence that abducible$$ holds for throw(_670,scissors), because
               abducible$ holds for throw(_670,scissors), because
                  it is assumed that there is no evidence that abducible$$ holds for throw(_670,scissors)
      rock beats scissors
   ∎

Thanks for getting back to me on this. Sorry for the delay. I will find and share the code as soon as I get a chance. Vacations will be intervening. The problem is when operating from Prolog’s top-level, which is how I’m accessing s(CASP) through swiplserver. In that context, maybe any example code will demonstrate the problem? Is there a fundamental reason we can’t get it to work in that environment?

I have also noticed a strange thing (again, I will follow up with better details) where if the predicate statement is #pred outer(inner(A,B),inner(A,C)) :: 'whatever'., A will be replaced with a concrete symbol, but not everywhere that it appears. I don’t know if that’s happening in the reasoning, or just in the human language generation.

I will also confirm that I’m not pulling an old version. I’m not exactly sure how Docker decides which steps in the image creation process need the cache discarded.