Home > Archive > Prolog > April 2007 > unification problems
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
unification problems
|
|
| Reuben Grinberg 2007-04-11, 7:04 pm |
| I have a function that unifies lists of pairs of things together:
unify([]).
unify([constraint(S,T)|Rest]) :- S = T, unify(Rest).
Why is the following failing:
|? - unify([constraint(X,nat)|constraint(Y,fu
nctionType(X,X))]).
instead of returning
X=nat
Y=functionType(nat,nat)
I'm using Sicstus, by the way.
thanks,
Reuben
| |
| Kosa Marton 2007-04-11, 7:04 pm |
| Reuben Grinberg wrote:
> I have a function that unifies lists of pairs of things together:
> unify([]).
> unify([constraint(S,T)|Rest]) :- S = T, unify(Rest).
>
> Why is the following failing:
> |? - unify([constraint(X,nat)|constraint(Y,fu
nctionType(X,X))]).
> instead of returning
> X=nat
> Y=functionType(nat,nat)
>
> I'm using Sicstus, by the way.
>
> thanks,
> Reuben
Try
|? - unify([constraint(X,nat),constraint(Y,fu
nctionType(X,X))]).
Your version is not a complete list with 'nil' at the end.
Cheers,
Marton
| |
| Reuben Grinberg 2007-04-11, 7:04 pm |
| Kosa Marton wrote:
> Reuben Grinberg wrote:
>
> Try
> |? - unify([constraint(X,nat),constraint(Y,fu
nctionType(X,X))]).
>
> Your version is not a complete list with 'nil' at the end.
>
> Cheers,
>
> Marton
Sweet -- that worked.
Thanks!
| |
| Reuben Grinberg 2007-04-11, 7:04 pm |
| Kosa Marton wrote:
> Reuben Grinberg wrote:
>
> Try
> |? - unify([constraint(X,nat),constraint(Y,fu
nctionType(X,X))]).
>
> Your version is not a complete list with 'nil' at the end.
>
> Cheers,
>
> Marton
What's the best way to write a test for this?
Up until now I've been writing
:- SomePredicate(some input.., expected output..).
and searching for "goal failed" in the output
However, for this unify function this doesn't really make sense.
When calling
unify([constraint(X,nat),constraint(Y,fu
nctionType(X,X))])
I want to make sure that X is unified to nat and Y is unified to
functionType(nat,nat) and that there are no other unifications that make
sense.
But it wouldn't make sense for me to write:
unify([constraint(nat,nat),constraint(fu
nctionType(nat,nat),functionType(nat,nat
))])
because this throws out important information regarding the test.
What do you guys suggest?
Thanks,
Reuben
| |
| Markus Triska 2007-04-12, 10:03 pm |
|
Reuben Grinberg <reuben.grinberg@aya.yale.edu> writes:
> I want to make sure that X is unified to nat and Y is unified to
> functionType(nat,nat) and that there are no other unifications that
> make sense.
First, what about this version:
unify([]).
unify([constraint(S,S)|Rest]) :- unify(Rest).
Second, a more stringent test case:
:- findall(X-Y, unify([constraint(X,nat),constraint(Y,f(
X,X))]),
[nat-f(nat,nat)]).
Finally, to automatically highlight failed test cases and syntax
errors in your program (using the Prolog system as checker), download
Emacs(-snapshot) >= 22, and put the following in your .emacs:
(add-hook 'prolog-mode-hook
(lambda ()
(require 'flymake)
(make-local-variable 'flymake-allowed-file-name-masks)
(make-local-variable 'flymake-err-line-patterns)
(setq flymake-err-line-patterns
'(("ERROR: (?\\(.*?\\):\\([0-9]+\\)" 1 2)
("Warning: (\\(.*\\):\\([0-9]+\\)" 1 2)))
(setq flymake-allowed-file-name-masks
'(("\\.pl\'" flymake-prolog-init)))))
(defun flymake-prolog-init ()
(let* ((temp-file (flymake-init-create-temp-buffer-copy
'flymake-create-temp-inplace))
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
(list "pl" (list "-q" "-t" "halt" "-s " local-file))))
M-x flymake-mode in a Prolog buffer then transparently reconsults your
program periodically and highlights lines with warnings/errors. This
is tailored for SWI Prolog; other systems may require adaptions.
--
comp.lang.prolog FAQ: http://www.logic.at/prolog/faq/
| |
| bart demoen 2007-04-12, 10:03 pm |
| On Wed, 11 Apr 2007 19:54:28 -0500, Reuben Grinberg wrote:
>
> I want to make sure that X is unified to nat and Y is unified to
> functionType(nat,nat) and that there are no other unifications that make
> sense.
>
> But it wouldn't make sense for me to write:
> unify([constraint(nat,nat),constraint(fu
nctionType(nat,nat),functionType(nat,nat
))])
>
> because this throws out important information regarding the test.
No ad-hoc suggestions this time :-)
The important thing to realise about testing software is that you can
look at the problem in the following way: you have two (maybe more,
but we'll do with two) ways of specifying the relation between "input" and
"output" [what constitutes input and output is more clear in a pure
functional language than in Java]. One way you have programmed into a
program P and you want to use the other way T as a tester. If you want to
automate the testing, you have to encode T as a program as well, and the
main difference between P and T becomes that P should deal with any input,
while T possibly only deals with particular input. The other important
difference is that you put more trust in T.
Surprisingly, that's about everything you need to know about testing
software, but see later :-)
So your problem is to find T once you have constructed P.
Oh, maybe not so. Maybe you should construct T first and then start
programming P.
Ah, maybe Prolog gives you a way of constructing T and P will be just
a copy of T.
....
Enough of this: when constructing T for Prolog programs, you must take
into account that a query has an instantiation state before execution
and one after execution. Since Prolog allows for non-declarative
predicates (var/1, ...) one can't in general capture the intended
meaning of a program in a ground query, even if your P does not use
such non-declarative preds. And the other way around.
However, the important thing to realise is the symmetry between P and T.
[later] you might want to get yourself involved in coverage etc. of
course, but that's the easy part :-)
Cheers
Bart Demoen
| |
|
| On Thu, 12 Apr 2007 21:15:49 +0200, bart demoen <bmd@cs.kuleuven.be>
wrote:
[...]
>Enough of this: when constructing T for Prolog programs, you must take
>into account that a query has an instantiation state before execution
>and one after execution. Since Prolog allows for non-declarative
>predicates (var/1, ...) one can't in general capture the intended
>meaning of a program in a ground query, even if your P does not use
>such non-declarative preds. And the other way around.
>
>However, the important thing to realise is the symmetry between P and T.
>
>
>
>[later] you might want to get yourself involved in coverage etc. of
>course, but that's the easy part :-)
By the way, there is well established methodology for testing Java,
C++, Smalltalk code, and one framework supporting this methodology is
JUnit - currently the de-facto standard in professional software
development. It is required that all code has corresponding JUnit
tests and test execution and reporting is automated (actually, in
commercial projects about 75% of the code are JUnit tests).
I have to do unit testing of Prolog programs, and it seems that
nothing even remotely similar to JUnit is available. There is also
very little about methodology of testing Prolog programs.
Do you know any tools, papers, thoughts or whatever that would address
testing large Prolog programs?
A.L.
| |
| Joachim Schimpf 2007-04-12, 10:03 pm |
| A.L. wrote:
>...
>
> I have to do unit testing of Prolog programs, and it seems that
> nothing even remotely similar to JUnit is available. There is also
> very little about methodology of testing Prolog programs.
>
> Do you know any tools, papers, thoughts or whatever that would address
> testing large Prolog programs?
For what it's worth, ECLiPSe has a small library(test_util),
which allows you to specify test patterns like
Goal should_give PostCondition.
Goal should_fail.
Goal should_throw Exception.
-- Joachim
| |
|
| On Thu, 12 Apr 2007 20:20:44 GMT, Joachim Schimpf <jschimpf@cisco.com>
wrote:
>A.L. wrote:
>
>For what it's worth, ECLiPSe has a small library(test_util),
>which allows you to specify test patterns like
>
>Goal should_give PostCondition.
>Goal should_fail.
>Goal should_throw Exception.
Thanks, good starting point...
A.L.
| |
| Darren Bane 2007-04-12, 10:03 pm |
| A.L. <fela@2005.com> wrote:
!snipped!
> I have to do unit testing of Prolog programs, and it seems that
> nothing even remotely similar to JUnit is available. There is also
> very little about methodology of testing Prolog programs.
>
> Do you know any tools, papers, thoughts or whatever that would address
> testing large Prolog programs?
SWI and Sicstus can run a package called PlUnit:
http://www.swi-prolog.org/packages/plunit.html
--
Darren Bane
| |
|
| On Thu, 12 Apr 2007 22:56:55 +0100 (BST), Darren Bane
<darren.bane@gmail.com> wrote:
>A.L. <fela@2005.com> wrote:
>
>!snipped!
>
>
>SWI and Sicstus can run a package called PlUnit:
>
> http://www.swi-prolog.org/packages/plunit.html
Thanks, this is exactly what I was looking for (I am using SICStus...)
A.L.
| |
|
| On Thu, 12 Apr 2007 22:56:55 +0100 (BST), Darren Bane
<darren.bane@gmail.com> wrote:
>A.L. <fela@2005.com> wrote:
>
>!snipped!
>
>
>SWI and Sicstus can run a package called PlUnit:
>
> http://www.swi-prolog.org/packages/plunit.html
Actually, SICStus port too restricted... It seems that I will do
myslef...
A.L.
| |
| Reuben Grinberg 2007-04-12, 10:03 pm |
| Markus Triska wrote:
> Reuben Grinberg <reuben.grinberg@aya.yale.edu> writes:
>
>
> First, what about this version:
>
> unify([]).
> unify([constraint(S,S)|Rest]) :- unify(Rest).
>
> Second, a more stringent test case:
>
> :- findall(X-Y, unify([constraint(X,nat),constraint(Y,f(
X,X))]),
> [nat-f(nat,nat)]).
>
This is perfect. Thanks.
As for Emacs 22 and flymake, I'm using my university computer science
account and the version installed there is 21. Oh well. Thanks for the
suggestion, though.
> Finally, to automatically highlight failed test cases and syntax
> errors in your program (using the Prolog system as checker), download
> Emacs(-snapshot) >= 22, and put the following in your .emacs:
>
> (add-hook 'prolog-mode-hook
> (lambda ()
> (require 'flymake)
> (make-local-variable 'flymake-allowed-file-name-masks)
> (make-local-variable 'flymake-err-line-patterns)
> (setq flymake-err-line-patterns
> '(("ERROR: (?\\(.*?\\):\\([0-9]+\\)" 1 2)
> ("Warning: (\\(.*\\):\\([0-9]+\\)" 1 2)))
> (setq flymake-allowed-file-name-masks
> '(("\\.pl\'" flymake-prolog-init)))))
>
> (defun flymake-prolog-init ()
> (let* ((temp-file (flymake-init-create-temp-buffer-copy
> 'flymake-create-temp-inplace))
> (local-file (file-relative-name
> temp-file
> (file-name-directory buffer-file-name))))
> (list "pl" (list "-q" "-t" "halt" "-s " local-file))))
>
> M-x flymake-mode in a Prolog buffer then transparently reconsults your
> program periodically and highlights lines with warnings/errors. This
> is tailored for SWI Prolog; other systems may require adaptions.
>
| |
| Jan Wielemaker 2007-04-13, 4:03 am |
| On 2007-04-12, A.L <fela@2005.com> wrote:
> On Thu, 12 Apr 2007 22:56:55 +0100 (BST), Darren Bane
><darren.bane@gmail.com> wrote:
>
> Actually, SICStus port too restricted... It seems that I will do
> myslef...
If you improve PlUnit or the SICStus port, please share the result. It
would be nice if there was one PlUnit and not 25 different versions.
The aim of porting it to SICStus was to support porting a program
from SWI to SICStus and verify the portability in the future.
Thanks --- Jan
| |
|
| On 13 Apr 2007 07:19:30 GMT, Jan Wielemaker <jan@nospam.ct.xs4all.nl>
wrote:
>On 2007-04-12, A.L <fela@2005.com> wrote:
>
>
>If you improve PlUnit or the SICStus port, please share the result. It
>would be nice if there was one PlUnit and not 25 different versions.
>The aim of porting it to SICStus was to support porting a program
>from SWI to SICStus and verify the portability in the future.
>
> Thanks --- Jan
OK, I will try to do the best...
A.L.
| |
|
|
|
|
|