Reputation: 44275
I setup the following rules to find if there is a relationship between two elements:
directReference(A,B) :- projectReferences(A,B).
transitiveReference(A,C) :- directReference(A,B),directReference(B,C).
transitiveReferenceD1(A,D) :- transitiveReference(A,C),directReference(C,D).
transitiveReferenceD2(A,E) :- transitiveReferenceD1(A,D),directReference(D,E).
Can I write a PrologScript that will check all these queries for a fact? Although I plan to use Ruby&Rake, someone is trying to do a non-interactive call from PHP here and it has not worked. I also saw this answer and tried Kaarel's answer. I just added a new opts_spec
:
opts_spec(
[ [opt(day), type(atom),
shortflags([d]), longflags(['term', 'day']),
help('name of day')]
, [opt(goal),
shortflags([g]), longflags([goal]),
help('goal to be called')]
, [opt(projectReferences), type(atom),
shortflags([pr]), longflags(['term', 'projectReferences']),
help('Project Reference lookup')]
]
).
I then compiled with:
.\swipl.exe -o day.exe -g main -c "D:\DevProjects\AskJoe\Output\Sample.pro"
And ran it with:
./day.exe -g "day(Sunday)"
And got error:
ERROR: Prolog initialisation failed: ERROR: validate_opts_spec/1: Domain error:
unique_atom' expected, found
term' (ambiguous flag)
My goal is to have this work:
./day.exe -g "transitiveReference('a','b')"
I don't like compiling a "day.exe" to run a script (according to the docs this often is not necessary), but I have found no other way to pass arguments to rules.
I saw a basic intro on swi-pl.org that has not helped much. It does not explain how to make the leap from the script.sh file example to the execution of ./eval 1+2
. In fact, the example is a comment so I'm totally lost
Upvotes: 2
Views: 446
Reputation: 44275
So I got this all working and then after a few runs everything just stopped. I started getting 'permission denied bad interpreter' errors. All I can say is that it has something to do with the hashBang. The workaround for me was to create a shell script around the call to swipl:
shellscript.sh
#!/bin/bash
swipl -s script4.pl 'projectReferences(A,D).'
Then I continued using aBathologist's example, but just took off the hashBang:
:- initialization main.
query :-
current_prolog_flag(argv, Argv),
concat_atom(Argv, ' ', Atom),
read_term_from_atom(Atom, Term, []),
call(Term).
main :-
catch(query, E, (print_message(error, E), fail)),
halt.
main :-
halt(1).
projectReferences(valueA, valueB) :- writeln('I was called!').
directReference(A,B) :- projectReferences(A,B).
transitiveReference(A,C) :- directReference(A,B),directReference(B,C).
transitiveReferenceD1(A,D) :- transitiveReference(A,C),directReference(C,D).
transitiveReferenceD2(A,E) :- transitiveReferenceD1(A,D),directReference(D,E).
Upvotes: 0
Reputation: 4098
Here is a very crude example of a PrologScript program that will read its arguments as a single goal (which may be compound), call it, and then terminate. It should work on *nix systems, and has been tested on OS X. It is just a slight variation of the example program given for using PrologScript in the SWI docs:
#!/usr/bin/env swipl
:- initialization main.
query :-
current_prolog_flag(argv, Argv),
concat_atom(Argv, ' ', Atom),
read_term_from_atom(Atom, Term, []),
call(Term).
main :-
catch(query, E, (print_message(error, E), fail)),
halt.
main :-
halt(1).
projectReferences(valueA, valueB) :- writeln('I was called!').
directReference(A,B) :- projectReferences(A,B).
transitiveReference(A,C) :- directReference(A,B),directReference(B,C).
transitiveReferenceD1(A,D) :- transitiveReference(A,C),directReference(C,D).
transitiveReferenceD2(A,E) :- transitiveReferenceD1(A,D),directReference(D,E).
After saving this file as, e.g., cli_test.pl
, you'll need to change the permissions on the file so that the operating system will recognize it as an executable:
chmod -x scratchboard.pl
After that, you should be able to call the file as as a normal executable from the command line:
$ path/to/the/file/scratchboard.pl 'transitiveReferenceD1(A,D).'
I was called!
Note:
query/0
will then retrieve this argument using current_prolog_flag/2
, read it as a Prolog term, and call it. catch/3
(in the body of main/0
) is triggered by an error or if projectReferences/2
is called successfully.Using library(optparse)
seems advisable for more complicated cli interface, but is not necessary for your stated aim of merely querying goals in a file.
I understand that getting the PrologScript approach to work on Windows is somewhat different. A bit of information can be fond here: http://www.swi-prolog.org/FAQ/PrologScript.html
Upvotes: 2