"I/O error in write on [stream] (Encoding cannot represent character)" when building latex

Hi everyone. I’m trying to compile my project’s documentation in latex. I get an error that I think has to do with utf-8 characters in a few source files. Here’s the error:

[debug]  ?- make_tex.
ERROR: I/O error in write on stream <stream>(000000000BF1A4B0) (Encoding cannot represent character)
ERROR: In:
ERROR:   [57] format(<stream>(000000000BF1A4B0),'~w',['?- list_mil_problem(list_last/2).\nPositive examples\n-----------------\nlist_last([a],a).\nlist_last([1,2],2).\nlist_last([a1,b2,c3],c3).\n\nNegative examples\n-----------------\n[]\n\nBackground knowledge\n--------------------\nhead/2:\nhead([A|B],A).\n\ntail/2:\ntail([A|B],B).\n\nempty/1:\nempty([]).\n\nMetarules\n---------\n(M1) ∃.P,Q,R,S ∀.x,y,z: P(x,y)← Q(x,z),R(z),S(x,y)\n(M2) ∃.P,Q,R,S,T ∀.x,y,z,u: P(x,y)← Q(x,z),R(z,u),S(u),T(z,y)\n(M3) ∃.P,Q,R,S,T,P1 ∀.x,y,z,u,v: P(x,y)← Q(x,z),R(z,u),S(u,v),T(v),P1(u,y)\ntrue.'])
ERROR:   [56] pldoc_latex:print_latex_token(code('?- list_mil_problem(list_last/2).\nPositive examples\n-----------------\nlist_last([a],a).\nlist_last([1,2],2).\nlist_last([a1,b2,c3],c3).\n\nNegative examples\n-----------------\n[]\n\nBackground knowledge\n--------------------\nhead/2:\nhead([A|B],A).\n\ntail/2:\ntail([A|B],B).\n\nempty/1:\nempty([]).\n\nMetarules\n---------\n(M1) ∃.P,Q,R,S ∀.x,y,z: P(x,y)← Q(x,z),R(z),S(x,y)\n(M2) ∃.P,Q,R,S,T ∀.x,y,z,u: P(x,y)← Q(x,z),R(z,u),S(u),T(z,y)\n(M3) ∃.P,Q,R,S,T,P1 ∀.x,y,z,u,v: P(x,y)← Q(x,z),R(z,u),S(u,v),T(v),P1(u,y)\ntrue.'),<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1552
ERROR:   [55] pldoc_latex:print_latex_tokens([code('?- list_mil_problem(list_last/2).\nPositive examples\n-----------------\nlist_last([a],a).\nlist_last([1,2],2).\nlist_last([a1,b2,c3],c3).\n\nNegative examples\n-----------------\n[]\n\nBackground knowledge\n--------------------\nhead/2:\nhead([A|B],A).\n\ntail/2:\ntail([A|B],B).\n\nempty/1:\nempty([]).\n\nMetarules\n---------\n(M1) ∃.P,Q,R,S ∀.x,y,z: P(x,y)← Q(x,z),R(z),S(x,y)\n(M2) ∃.P,Q,R,S,T ∀.x,y,z,u: P(x,y)← Q(x,z),R(z,u),S(u),T(z,y)\n(M3) ∃.P,Q,R,S,T,P1 ∀.x,y,z,u,v: P(x,y)← Q(x,z),R(z,u),S(u,v),T(v),P1(u,y)\ntrue.'),...|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1517
ERROR:   [54] pldoc_latex:print_latex_tokens([nl_exact(2),...|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1515
ERROR:   [53] pldoc_latex:print_latex_tokens([:,...|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [52] pldoc_latex:print_latex_tokens([elements,:|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [51] pldoc_latex:print_latex_tokens([' ',elements|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [50] pldoc_latex:print_latex_tokens([problem,' '|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [49] pldoc_latex:print_latex_tokens([' ',problem|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [48] pldoc_latex:print_latex_tokens(['MIL',' '|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [47] pldoc_latex:print_latex_tokens([' ','MIL'|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [46] pldoc_latex:print_latex_tokens([cmd(item),' '|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [45] pldoc_latex:print_latex_tokens([indent(4),...|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [44] pldoc_latex:print_latex_tokens([nl_exact(2),...|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1515
ERROR:   [43] pldoc_latex:print_latex_tokens([code('?- list_config.\nexample_clauses(call)\nexperiment_file(data/examples/recursive_folding.pl,recursive_folding)\ngeneralise_learned_metarules(false)\ngeneralised_examples(fully)\nlearned_metarules_printing(pretty)\nlearner(louise)\nmax_invented(1)\nmetarule_learning_limits(metasubstitutions(1))\nminimal_program_size(2,inf)\nrecursion_depth_limit(dynamic_learning,none)\nrecursive_reduction(false)\nreduce_learned_metarules(false)\nreduction(plotkins)\nresolutions(5000)\nsymbol_range(predicate,[P,Q,R,S,T])\nsymbol_range(variable,[X,Y,Z,U,V,W])\ntheorem_prover(resolution)\nunfold_invented(false)\ntrue.'),...|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [42] pldoc_latex:print_latex_tokens([nl_exact(2),...|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1515
ERROR:   [41] pldoc_latex:print_latex_tokens([:,...|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [40] pldoc_latex:print_latex_tokens([configuration,:|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [39] pldoc_latex:print_latex_tokens([' ',configuration|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
ERROR:   [38] pldoc_latex:print_latex_tokens([good,' '|...],<stream>(000000000BF1A4B0)) at c:/program files/swipl/library/doc_latex.pl:1518
^  Exception: (57) format(<stream>(000000000BF1A4B0), '~w', ['?- list_mil_problem(list_last/2).\nPositive examples\n-----------------\nlist_last([a],a).\nlist_last([1,2],2).\nlist_last([a1,b2,c3],c3).\n\nNegative examples\n-----------------\n[]\n\nBackground knowledge\n--------------------\nhead/2:\nhead([A|B],A).\n\ntail/2:\ntail([A|B],B).\n\nempty/1:\nempty([]).\n\nMetarules\n---------\n(M1) ∃.P,Q,R,S ∀.x,y,z: P(x,y)← Q(x,z),R(z),S(x,y)\n(M2) ∃.P,Q,R,S,T ∀.x,y,z,u: P(x,y)← Q(x,z),R(z,u),S(u),T(z,y)\n(M3) ∃.P,Q,R,S,T,P1 ∀.x,y,z,u,v: P(x,y)← Q(x,z),R(z,u),S(u,v),T(v),P1(u,y)\ntrue.']) ? abort
% Execution Aborted

The reason must have something to do with the quantifiers and left-arrow used in some places, like the following:

(M1) ∃.P,Q,R,S ∀.x,y,z: P(x,y)← Q(x,z),R(z),S(x,y)

Is this something I can correct in latex or is it something I can fix in SWI-Prolog, e.g. with a prolog flag?

I’m uploading the two files I used to build the latex in case they help:

make_tex.pl (4.1 KB)
make_tex_configuration.pl (1.5 KB)

I start the compilation with a call to make_tex/0, defined in make_tex.pl. This gathers necessary files and passes them to doc_latex/3. The source file has instructions to run it.

The other file is the configuration for make_tex.pl. I used pldoc.sty as a style file without any changes.

Btw, I can’t remember writing that code for make_tex. I probably copied it from somewhere on the SWI-Prolog website. Or not. I can’t remember writing most of the code that I seem to have written :slight_smile:

1 Like

Are you on Windows?

See: Unicode code point for U+10000 on Windows OS. Use in string results in Illegal character code

1 Like

I’m on windows- don’t ask me why :slight_smile:

I’ll try all this with wsl. Thanks, Eric.

Before taking the time to install WSL did you look for other UTF characters below U+10000?

See: Shapecatcher

Using SWI-Prolog on Windows

Welcome to SWI-Prolog (threaded, 64 bits, version 8.5.0-49-g2f46def0c)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- C = "\U00000061".
C = "a".

?- C = "\U00002190".
C = "←".

?- C = "\U000020d6".
C = "⃖".

?- C = "\U000002ff".
C = "˿".

That is unlikely to help. The math symbols are mostly well below 0xFFFF. That is actually certain because it can read them. There are a few problems. Your Windows locale doesn’t cause Prolog to switch to UTF-8. You can fix that using

:- set_prolog_flag(encoding, utf8).

Next,you must be lucky that LaTeX picks up the UTF-8. Then you need to include the LaTeX package to handle Unicode input (forgot which one that is).

The other route would be for the LaTeX generator to translate the Unicode characters to traditional LaTeX commands and just produces ASCII text. Of course the disadvantage is that we need to create a table for these or get that table from somewhere.

2 Likes

Thanks Eric. There shouldn’t be any. Sometimes Greek creeps into my source files but I quickly catch it and eliminate it.

Thanks, Jan. I was in the middle of updating my wsl install to be able to update to the latest swi package for ubuntu, which I’d like to do anyway.

So I left this aside and added the prolog encoding flag to my project load file as you said and also added the latex package you probably meant:

\usepackage[utf8]{inputenc}

I managed to run my make_tex/0 after that without errors (on windows) and I built my documentation with pdflatex - not without errors. But the errors don’t seem to stop the building of the pdf, so that’s fine.

I get lots of overful boxes etc though, especially with long paths (listed as titles in the TOC) (yeah, because I just had to build a TOC) or long predicate signatures etc (I mean the name of the predicate and its arguments sometimes with modes and types and det/nondet etc).

I wonder if there’s something I can do abou thtis? For example, does PlDoc somehow accept instructions to format structured comments into latex in a particular manner?

Something else. I think that the latex for the documentation is created by translating the markdown of the structured comments into latex.

Something that has caught me a bit by surprise is that when I add headers with a single-underline in my comments, they end up as sections with their own numbers in the latex.

For example, I often have a motivation section in some structured comments or in module comments:

/** <module> Borker for borked borkings

Motivation
----------

This module includes predicates for borking and unborking borked borkings.
*/

Or, in a predicate:

%!    unbork_the_borked(+Borked, -Unbork) is nondet.
%     
%     Unbork a borked bork.
%
%    Motivation
%    ----------
% 
%    Sometimes a bork is borked and we want to unbork it.

When I generate latex from structured comments like that, the “Motivation” section becomes a numbered section in the documentation, e.g. 10.1 or something like that. This makes for a very confusing layout when an un-numbered section that has a predicate’s signature as a title is followed by a section with a numbered header, indended under the predicate’s signature. That also plays havoc with the number of sections throughout the paper .

What is the right way to handle this?

I guess writing better LaTeX macros? I always try to keep code boxes small and signatures short. Surely it is possible to write LaTeX macros that do a better job than the rather simple ones I wrote. I’ll leave that as an exercise to the user though :slight_smile: Willing to merge a PR!

As is, I think the only solution is to write e.g.

__Motivation__

I’m not aware of a markdown notation for “unnumbered sections” as Latex’s \section*{Title}. That might be a better alternative. Given some syntax it should be easy to implement (extend doc_wiki.pl to recognise it and the backends to emit the right code).

Yeah, I know, I should contribute more than just questions. I’ll see what I can do.

Oh, right, I think that will work. I just didn’t know what would be the right syntax for a sub-header (with respect to the predicate signature. But having unnumbered sections might be useful. I’ll try to have a look at doc_wiki.pl :slight_smile:

I think the main question is what the Markdown should be to distinguish a numbered from an unnumbered section.

Alright, sorry, I got carried away. I think I’ll to read about markdown and see if there’s something there already.

To clarify, this is not just for my sake, yes? There’s a more general need to have un-numbered sections in latex, similar to \section*{} like you say? Otherwise, I can live with __motivation__.

Un-numbered seem to have some demand. I won’t call it critical. If it is not critical to you, just leave it and wait for someone who considers it critical :slight_smile:

I guess it’s not critical. So I’ll just pick at it desultorily until my embarassment wanes.

1 Like