1:- module(sentence, [
    2      generate_answer/2
    3   ]).    4
    5:- use_module(library(race/util)).    6
    7generate_answer(proof(Entities), Answer) :-
    8   get_substitutions(Entities, Substitutions, Entities_Without_Substitutions),
    9   substitutions_fragment(Substitutions, Substitutions_Fragment),
   10   maplist(fragment, Entities_Without_Substitutions, EWS_Fragments),
   11   join(" and ", EWS_Fragments, EWS_Fragment),
   12   join(" and ", [ Substitutions_Fragment, EWS_Fragment], Answer).
   13
   14generate_answer(not(Entities), Answer) :-
   15   maplist(fragment, Entities, Fragments),
   16   join(" ", Fragments, Answer).
   17
   18get_substitutions(Entities, Substitutions, Entities_Without_Substitutions) :-
   19   maplist(get_only(substitution), Entities, Substitutions_R, Entities_Without_Substitutions_R),
   20   flatten(Substitutions_R, Substitutions),
   21   flatten(Entities_Without_Substitutions_R, Entities_Without_Substitutions).
   22
   23get_only(What, Entity, Selected, NonSelected) :-
   24   ( Entity =.. [What|_] ->
   25     Selected = [ Entity ],
   26     NonSelected = []
   27   ; Selected = [],
   28     NonSelected = [ Entity ]).
   29
   30substitutions_fragment([], '') :- !.
   31substitutions_fragment(Substitutions, JoinedFragments) :-
   32   maplist(fragment, Substitutions, Fragments),
   33   join(" and ", Fragments, JoinedFragments).
   34
   35fragment(substitution(Left, Right), Fragment) :-
   36   !,
   37   string_list_concat([Left, " as ", Right], Fragment).
   38fragment(fact(F), Fragment) :-
   39   !,
   40   string_concat("the known fact that ", F, FragmentWithDot),
   41   string_concat(Fragment, ".", FragmentWithDot).
   42fragment(X, Fragment) :-
   43   % unknown case
   44   X =.. [_Type, Term|_],
   45   Fragment = Term