How to catch compile errors when using consult

I’m working on a Python project that interfaces with Prolog using PySwip. I’m trying to find a reliable way to catch compilation errors when loading Prolog code from Python. Here’s a minimal example that illustrates my problem:

from pyswip import Prolog
import tempfile
import os

def compile_prolog_code(code):
    prolog = Prolog()

    # Create a temporary file to store the Prolog code
    with tempfile.NamedTemporaryFile(mode='w', suffix='.pl', delete=False) as temp_file:
        temp_file.write(code)
        temp_file_path = temp_file.name

    try:
        prolog.consult(temp_file_path)
        print("Prolog code compiled successfully.")
        return True
    except Exception as e:
        print(f"Error compiling Prolog code: {e}")
        return False
    finally:
        # Clean up the temporary file
        os.unlink(temp_file_path)
# Test case with a syntax error (missing period)
test_code = """
foo(X) :- bar(X).
bar(1).
bar(2)  % Missing period here
"""

success = compile_prolog_code(test_code)
print(f"Compilation {'succeeded' if success else 'failed'}")

The above code returns True despite a compilation error. This is b/c consult/1 always succeeds even if there are errors in the code being loaded. Is there a way to make it fail and return False in the above code?

You could write a wrapper around consult/1 that uses message_hook/3 to count errors and warnings. When consult completes and there are errors/warnings (your choice), use unload_file/1 to discard the loaded file and throw an exception. To do it properly you need to probably should use source_location/2 to verify the message is related to the file being loaded.

The problem is that SWI-Prolog file loading may have side effects due to executed directives that are unknown and thus cannot be undone. unload_file/1 just wipes the clauses that are associated with the file and the admin data that the file was loaded.

Related, loading a file may load other files. You can keep track of that and decide whether or not to unload these as well.

If the above limitations do not bother you, you should be fine :slight_smile:

1 Like

As this has been asked for before, here is an example implementation.

consult_ex.pl (1.1 KB)

2 Likes

Thanks. Your solution works!