Skip to content

Commit 380f3ae

Browse files
committed
Bugfix clause/2: TypeError
The presence of Var within the unify method caused TypeErrors.
1 parent 395b3ba commit 380f3ae

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed

problog/clausedb.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,29 @@ def _compile(self, struct, variables=None, scope=None):
564564
else:
565565
raise ValueError("Unknown structure type: '%s'" % struct)
566566

567+
def _create_ints(self, term):
568+
"""
569+
Convert all occurrences of Var into ints.
570+
571+
For example, when term = Term('a', Var('V_1'), Constant(3)), this returns Term('a', 1, Constant(3))
572+
This assumes each Var has functor V_{var_id} with var_id some int value.
573+
This is opposite to the method _create_vars(term).
574+
:param term: The term to replace all Var occurrences in.
575+
:type term: Term
576+
:return: The same term but with all occurrences of Var replaced with their corresponding int value.
577+
:rtype: Term
578+
"""
579+
if type(term) == Var:
580+
assert term.functor[:2] == "V_"
581+
# Convert V_{digit} to an int of value {digit}
582+
return int(term.functor[2:])
583+
else:
584+
args = [self._create_ints(arg) for arg in term.args]
585+
term = term.with_args(*args)
586+
if term.probability is not None:
587+
term = term.with_probability(self._create_ints(term.probability))
588+
return term
589+
567590
def _create_vars(self, term):
568591
if type(term) == int:
569592
return Var("V_" + str(term))

problog/engine_builtin.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,10 @@ def _builtin_clause(head, body, database=None, **kwd):
268268
b = Term("true")
269269

270270
try:
271-
unify_value(head, h, {})
272-
unify_value(body, b, {})
271+
# Perform unifying checks before storing the results
272+
# can't do unify_value with Vars, first replace them with ints (database._create_ints)
273+
unify_value(head, database._create_ints(h), {})
274+
unify_value(body, database._create_ints(b), {})
273275
result.append((h, b))
274276
except UnifyError:
275277
pass

test/clause_pred.pl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
%Expected outcome:
2+
% clause(a,b(V_0)) 1
3+
% clause(c(d(V_0)),b(V_0)) 1
4+
5+
a :- b(X).
6+
7+
query(clause(a,b(Y))).
8+
9+
c(d(X)) :- b(X).
10+
11+
query(clause(c(X),Y)).

test/cut_2.pl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
%Expected outcome:
2+
% ism(2,3,3) 1
3+
% ism(2,3,2) 1
4+
% ism(6,1,6) 1
5+
% ism(6,1,1) 0
6+
7+
:- use_module(library(cut)).
8+
9+
% if X =< Y, then Z = Y, otherwise Z = X
10+
m(1, X,Y,Z):- X =< Y, Z = Y.
11+
m(2, X,Y,X).
12+
13+
ism(X, Y, Z) :- cut(m(X,Y,Z)).
14+
15+
query(ism(2,3,Z)).
16+
query(ism(2,3,2)).
17+
query(ism(6,1,6)).
18+
query(ism(6,1,1)).

0 commit comments

Comments
 (0)