Term_expansion/2 to make Prolog syntax look more like classical FOL

Hi!

I am trying to get Prolog code look more like FOL, and I used op/3 and term_expansion/2 to do this.

:- op(1200, xfx, ==>).
:- op(1000, xfy, /\).
:- op(1100, xfy, \/).

term_expansion(A ==> B, B:- A).
term_expansion(A /\ B, A, B).
term_expansion(A \/ B, A; B).

man(X) /\ unmarried(X) ==> bachelor(X).

man(john).
man(peter).
unmarried(john).

main:-bachelor(X), writeln(X), nl, fail.

But i get the error ERROR: bachelor/1: Undefined procedure: (/)/2
Exception: (5) man(_1740)/\unmarried(_1740) ?

Can anyone help? Thanks!

It is great that are making use of both StackOverflow and this site. It might help others if you included links to your previous questions so they can see the history. :slight_smile:

Note you’re missing parenthesis in your term_expansion clauses.
After I corrected them, still /\ and \/ weren’t expanded, so maybe…

:- module(fol, [main/0]).

:- op(1200, xfx, ==>).
:- op(1000, xfy, /\).
:- op(1100, xfy, \/).

term_expansion(A ==> B, B:- A).
goal_expansion(A /\ B, (A, B)).
goal_expansion(A \/ B, (A; B)).

man(X) /\ unmarried(X) ==> bachelor(X).

man(john).
man(peter).
unmarried(john).

main:-bachelor(X), writeln(X), nl, fail.

It yields an answer now:

?- main.
john
1 Like

Thanks, perfect.

If do it nice you do of course like this :slight_smile:

:- op(1200, xfx, ⇒).
:- op(1000, xfy, ∧).
:- op(1100, xfy, ∨).
2 Likes

@jan Even better :slight_smile: But i got the error “Illegal character” using ⇒, ∧, and ∨.

By they way, thank you very much for making SWI!

You need Unicode support. The above works fine on my Ubuntu machine which since long defaults to using UTF-8. SWI-Prolog picks up the default locale, at least on most Unix-like systems. So, what is your setup? OS? Locale settings? Editor? It may all matter. You get a reliable result on any system if you can use an editor that can add a Unicode BOM marker at the start of the file.

You can find Prolog’s idea of the encoding using

?- current_prolog_flag(encoding, E).

That is either some encoding name or text, meaning it doesn’t understand what the encoding is, but it relies on the C library to translate the input and output to Unicode.

Aha, OK. I get E = text. in response to the current_prolog_flag query. I have MacOs 10.13.6 and use Sublime text as an editor (and to run code).

Now things get complicated :frowning: It differs whether using the window app from the binary distribution or the swipl console app. Otherwise I just hope someone has the answer. I only have a 12 year old Mac on which I (very slowly) compile SWI-Prolog …

I’ll probably find some solution, thanks for your help!

For the sake of completeness, here is an example that brings together your suggestions:

:- op(1200, xfx, ⇒).
:- op(1000, xfy, ∧).
:- op(1100, xfy, ∨).
:- op(900, fy, ¬).
term_expansion(A ⇒ B, B:- A).
goal_expansion(A ∧ B, (A, B)).
goal_expansion(A ∨ B, (A; B)).
goal_expansion(¬A, \+A).

man(john).
unmarried(mark).
unmarried(X) ∧ man(X) ⇒ bachelor(X).

main:-unmarried(X), writeln(X).

The solution to the Illegal character error in Sublime text is: using Save with Encoding -> UTF-8 with BOM in Sublime text.

On linked-in someone asked to provide examples of code for counting from one to twenty.

I decided to add the following code, while encouraging a declarative reading:

forall(between(1,20,X), writeln(X)).

However, someone then asked from where the order comes from.

Which actually showed how the procedural reading “lurks” behind the scene …

Dan

I understand that person, by myself did the same question, and was amazed by the implementation :slight_smile: .

Then, library(aggregate) with foreach/2 come into play. Maybe that’s more an interesting showcase of a round trip into procedural programming.

Here is a trial without assuming order …

bagof(X, between(1,20,X), Xs), sort(Xs, SortedXs), maplist(writeln, SortedXs).

Although, it is declarative, somehow the declarative reading is lost … i like the use of forall hinting at the universal quantifier – the term sort is in imperative language – and maplist is also imperative in flavor …

Dan