user3170496
user3170496

Reputation:

Way to make Prolog syntax look like first order logic syntax?

I am looking for ways to make a Prolog program "look" more like first order logic. Things I would like to have are for example:

Or is there other software that already implements this?

Thanks in advance!

/JC

Update 20190313 I followed the suggestions in the answers below and tried 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 following error:

ERROR: bachelor/1: Undefined procedure: (/\)/2
   Exception: (5) man(_1740)/\unmarried(_1740) ? 

Only using the op/3 and term_expansion/3 for ==> however works as expected. Not sure why this is so...

Upvotes: 1

Views: 157

Answers (3)

repeat
repeat

Reputation: 18726

This answer refers to your updated question ("Update 20190313").

Be careful when defining operators:

  1. Don't redefine standard operators, changing their specifier/precedence.

    This can introduce errors in existing code which are very hard to find.

  2. Weigh benefits and costs upfront.

    Aim at readability, shorter code, and fewer parentheses.

    Keep in mind that using too many custom Prolog operators can also obfuscate code and confuse the reader.

  3. Think twice before using standard operators in different domains.

    Let's take the predefined (\/)/2 as an example.

    • It is an evaluable functor in arithmetic expressions—used with (is)/2, (=:=)/2, (<)/2, etc.

    • clpfd uses it for representing set unions like 1..3 \/ 5..7—fine!

    • However, using it for denoting list concatenation is questionable.


Let's get to your actual question!

Consider these queries decomposing some terms using (=..)/2 ("univ"):

?- term_expansion(A /\ B, A, B) =.. Xs.
Xs = [term_expansion, A/\B, A, B].

?- term_expansion(A \/ B, A; B) =.. Xs.
Xs = [term_expansion, A\/B, (A;B)].

So it's term_expansion/2 for (\/)/2, but term_expansion/3 for (/\)/2!

The bottom line: (',')/2 terms as arguments need parentheses.

?- term_expansion(A /\ B, (A,B)) =.. Xs.
Xs = [term_expansion, A/\B, (A,B)].

Upvotes: 0

櫻井洋志
櫻井洋志

Reputation: 53

Use term_expansion/2 that is macro of Prolog on SWI-Prolog:

% calc.pl
:- op(1200,xfx,--).
term_expansion(A--B,B:-A).

integer(I)
--%----------------------- (E-Int)
I => I.

E1=>I1, E2=>I2, I is I1+I2
--%----------------------- (E-Add)
E1+E2 => I.

:- 1+2+3=>6.
:- 1+2+3=>I,writeln(I).
:- halt.

and run

$ swipl calc.pl
6

Upvotes: 4

mat
mat

Reputation: 40768

Here are a few Unicode characters that can help you:

¬ 

→ ⇒

← ⇐

∨ ∧

∀ ∃

I leave defining suitable precedences as a challenge, using op/3.

Once you have these definitions, you can write first-order sentences with them. You can then convert these sentences to Prolog, or interpret them with Prolog.

Upvotes: 3

Related Questions