title: What does Prolog assert/1 do with the term it is passed?
body: <p>I'm trying to understand what assert and retract do with the term they are passed.  If I run the following:</p>
  
  <pre><code>?- assertz(item(first)).
  true.
  
  ?- assertz(item(second)).
  true.
  
  ?- assertz((item(Y) :- =(Y, third), writeln(Y))).
  true.
  
  ?- retract(item(X)).
  X = first ;
  X = second ;
  false.
  </code></pre>
  
  <p>retract/1 removes all of the items but my writeln/1 is never called, so it appears retract is not actually <em>resolving</em> the term it is passed.  It looks like it is doing some special operation where it:</p>
  
  <ul>
  <li>Unifies the term with only facts (i.e. rules with no tail) in the database</li>
  <li>Retracts each one after applying the substitution from unification</li>
  </ul>
  
  <p>Is this right? Or is something else happening here?</p>
  
  <p>Said another way: If I write my own single argument rule, Prolog does not automatically unify item(X) with the database and iterate through all facts that are item/1. It just gives me item(X).  How is retract doing its magic?</p>
  
  <pre><code>?- assertz((myRule(X) :- writeln(X))).
  true.
  
  ? myRule(item(X)).
  item(_2556)
  true.
  </code></pre>
  
  <p><strong>Answer with further clarification:</strong>
  Based on the answer by User9213, it appears that the answer is "retract (but not assert!) has a funny behavior where it does a simple unification of its term before it does something to the database".  I'm left wondering why other built-in functions that I've seen (like atom/1 and writeln/1) don't appear to do this. Maybe it is more common than I've experienced? </p>
  
  <p>For consistency, it seems like retract should have required ground terms and if the user wanted to do something like my above example, they could have done this:</p>
  
  <p>?- (item(X), retract(item(X))).</p>
  
  <p>It all makes me think I'm missing something or maybe these built in functions were just inconsistently designed? Any clarification that would explain that would be great.</p>