3

I have some predicates that I define using asserts in Prolog.

I am using current_predicate/1 in order to know whether the assert has been run or not (only one value needs to be asserted).

However, swipl keeps complaining:

Warning: The predicates below are not defined. If these are defined
Warning: at runtime using assert/1, use :- dynamic Name/Arity.
Warning: 
Warning: amountOfStudentsInCourseAsserted/2, which is referenced by

So, I added the :- dynamic amountOfStudentsInCourseAsserted/2, but unfortunately, this adds the predicate to the current_predicate(Predicate).. Therefore I cannot use current_predicate/1 anymore if I am using this dynamic naming.

Is there another predicate like current_predicate/1that isn't true for dynamic names?

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
Kevin Van Ryckegem
  • 1,915
  • 3
  • 28
  • 55

2 Answers2

1

You can use in alternative the predicate_property/2 built-in predicate and the number_of_clauses/1 property.

Paulo Moura
  • 18,373
  • 3
  • 23
  • 33
  • Are you sure this should work? In the manual: `Fails for foreign predicates.` and it does: `clause_property(examsListAsserted, number_of_clauses). false` – Kevin Van Ryckegem Dec 28 '15 at 07:15
  • Re-read my answer. Your comment cites a different built-in predicate and a different property. – Paulo Moura Dec 28 '15 at 09:10
  • I tried using predicate_property first, then tested clause_property. I copy pasted the wrong item. But it's still the same result unfortunately: `predicate_property(examsListAsserted, number_of_clauses). false.` It's always false – Kevin Van Ryckegem Dec 28 '15 at 09:11
  • 2
    The property is `number_of_clauses/1`, not `number_of_clauses/0`. I.e. the property have one argument, which is, as the name indicates, the number of clauses of the predicate. – Paulo Moura Dec 28 '15 at 10:25
1

The :- dynamic declaration is appropriate, as it will make the symbol known in the database. Then just attempt to match (with appropriate arguments, ignored in the following sample) before asserting:

...
(  amountOfStudentsInCourseAsserted(_,_)
-> true
;  assert(amountOfStudentsInCourseAsserted(X,Y))
),
...
CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • 2
    s(X). A tad bit safer would be `( clause(amountOfStudentsInCourseAsserted(_,_), _) -> ...` – false Dec 28 '15 at 11:41