# Beginner's question: why is this happening?

**URL:** <https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309>\
**Category:** Help!\
**Created:** [August 18, 2021, 12:01pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309 "2021-08-18T12:01:14Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![davidkettle](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/davidkettle/32/3669_2.png) [@davidkettle](https://swi-prolog.discourse.group/u/davidkettle)\
**Post date:** [August 18, 2021, 12:01pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/1 "2021-08-18T12:01:14Z")

</div>

I’m using: SWI-Prolog version 8.2.4 under Windows 7 (64-bit)

I want the code to: Code a generative music system

My code looks like this:

```prolog
pitch-name(c).
pitch-name(cf).
pitch-name(cs).
pitch-name(d).
pitch-name(df).
pitch-name(ds).
pitch-name(e).
pitch-name(ef).
pitch-name(es).
pitch-name(f).
pitch-name(ff).
pitch-name(fs).
pitch-name(g).
pitch-name(gf).
pitch-name(gs).
pitch-name(a).
pitch-name(af).
pitch-name(as).
pitch-name(b).
pitch-name(bf).
pitch-name(bs).

```

But what I’m getting is:

```prolog
?- pitch-name(X).
X = c ;
X = cf ;
X = cs ;
X = d ;
X = df ;
X = ds ;
X = e ;
X = ef ;
X = es ;
X = f ;
X = ff ;
X = fs ;
X = g ;
X = gf ;
X = gs ;
X = a ;
X = af ;
X = (as) ;
X = b ;
X = bf ;
X = bs.

?- 

```

Why is the line with `as` formatted the way it is, instead of `X = as ;` like all the other lines?

Thanks.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 18, 2021, 12:06pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/2 "2021-08-18T12:06:09Z")

</div>

> [@davidkettle](#):
>
> Why is the line with `as` formatted the way it is

`as` is a defined [operator](https://www.swi-prolog.org/pldoc/man?section=operators).

```prolog
?- current_op(P,T,as).
P = 700,
T = xfx.

?- current_op(P,T,a).
false.

```

---

<div class="post-metadata">

**Author:** ![davidkettle](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/davidkettle/32/3669_2.png) [@davidkettle](https://swi-prolog.discourse.group/u/davidkettle)\
**Post date:** [August 18, 2021, 12:17pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/3 "2021-08-18T12:17:15Z")

</div>

Thanks! I thought it might be defined already, but I couldn’t find any reference when I searched for ‘as’ in the online documentation. Where can I find a description of it? Is this liable to cause a problem, or can I just ignore it?

---

<div class="post-metadata">

**Author:** ![davidkettle](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/davidkettle/32/3669_2.png) [@davidkettle](https://swi-prolog.discourse.group/u/davidkettle)\
**Post date:** [August 18, 2021, 12:41pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/5 "2021-08-18T12:41:31Z")

</div>

It still displays ’ (as) ’ when I run the query. But this seems to work, so I guess I won’t worry about it, unless I run into a problem later.

```prolog
?- pitch-name(as).
true.

?-

```

Thanks again.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 18, 2021, 1:00pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/6 "2021-08-18T13:00:42Z")

</div>

`as` is an operator for two syntactic constructs. One is importing predicates under a different name. This allows for example:

```
:- use_module(library(lists), [member/2 as element_of]).

```

The other is to define some property combinations, notably inherited from XSB Prolog. For example:

```
:- table p/1 as incremental.

```

It is documented in the table at [SWI-Prolog -- Manual](https://www.swi-prolog.org/pldoc/man?section=operators)

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [August 18, 2021, 1:02pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/7 "2021-08-18T13:02:58Z")

</div>

You have chosen a peculiar name for your predicate. When you write it as it is, you have defined a predicate `-/2` with `pitch` in the first argument and `name(X)` in the second. So, you could do like this:

```prolog
?- X-name(c).
X = pitch.

```

Maybe that was your intention all along.

---

<div class="post-metadata">

**Author:** ![davidkettle](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/davidkettle/32/3669_2.png) [@davidkettle](https://swi-prolog.discourse.group/u/davidkettle)\
**Post date:** [August 18, 2021, 1:07pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/8 "2021-08-18T13:07:30Z")

</div>

Thanks. Is it considered bad practice to define something with a name that’s already in use, as long as you don’t need to use the pre-defined operator? I’m guessing that it would “mask” the pre-defined operator, but at the moment I don’t see any need to use it.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [August 18, 2021, 1:11pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/9 "2021-08-18T13:11:32Z")

</div>

I can’t answer for Jan but I wouldn’t be bothered by this overlap between your atom `as` and the predefined operator.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 18, 2021, 1:28pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/10 "2021-08-18T13:28:31Z")

</div>

It is completely harmless. `as` only has a special meaning in the described context. In any other context it is just the word `as` without any meaning. That is how Prolog works. For example, `1+2` is to Prolog just the term `+(1,2)`. It is in no way related to arithmetic. Only when you write e.g. `A is 1+2` _as a goal_ it gets a meaning. Used as a _goal_ (query), is/2 becomes a _predicate_ and is/2 gives a meaning to `1+2`, binding `A` to `3`.

The Prolog REPL (toplevel) prints answers such that they are valid Prolog terms and the Prolog standard requires `A = as` to be written as `A = (as)` because `as` is an operator. That is why you see what you see.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 18, 2021, 4:53pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/11 "2021-08-18T16:53:21Z")

</div>

> [@davidkettle](#):
>
> ```prolog
> pitch-name(c).
> 
> ```

You probably meant `pitch_name(c).` (with an underscore). It’ll work with `-`, but it’s probably not what you meant.

```prolog
?- write_canonical(pitch-name(c)).
-(pitch,name(c))

?- write_canonical(pitch_name(c)).
pitch_name(c)

```

---

<div class="post-metadata">

**Author:** ![davidkettle](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/davidkettle/32/3669_2.png) [@davidkettle](https://swi-prolog.discourse.group/u/davidkettle)\
**Post date:** [August 19, 2021, 1:21pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/13 "2021-08-19T13:21:38Z")

</div>

You’re correct, I thought the hyphen would be treated as part of the name, not as an operator. But when I test it, it seems to work anyway. Why don’t I get an error like the following?

```prolog
?- name(c).
ERROR: Unknown procedure: name/1
ERROR: However, there are definitions for:
ERROR: name/2
false.

```

My question was about something else, but thanks for pointing this out.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 19, 2021, 1:54pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/14 "2021-08-19T13:54:29Z")

</div>

Another variation of `as/2` as an operator.

[Composing modules from other modules](https://www.swi-prolog.org/pldoc/man?section=reexport)

> :- reexport(module\_6, except([pred/1 as mypred])).

---

<div class="post-metadata">

**Author:** ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)\
**Post date:** [August 19, 2021, 5:09pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/15 "2021-08-19T17:09:54Z")

</div>

> [@davidkettle](#):
>
> Why don’t I get an error

In Prolog, an atom has some peculiar handling of the character class used routinely for arithmetic operators. And since we can use any atom as a functor, you are defining facts for ‘-’/2, as @Boris explained very well.  
Arithmetic expressions are a DSL (Domain Specific Language), with specific rules enforced by is/2, and there ‘-’/2, or ‘-’/1, find their use (are interpreted) . But there are other domains where expression are useful, as you just found out 🙂

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 19, 2021, 6:10pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/16 "2021-08-19T18:10:45Z")

</div>

> [@davidkettle](#):
>
> I thought the hyphen would be treated as part of the name, not as an operator

When you defined `pitch-name(c)`, you actually defined the fact `'-'(pitch,name(c))`. So, everything “works” because of the way term unification is done; but under the covers it’s slightly different from what you expect – it looks for the fact `'-'` with two arguments: `pitch` and `name(c)`. This also has an effect on efficiency, because term indexing doesn’t work as well with such terms. So, it’s not “wrong”, but it could be confusing (e.g., if you wanted to put a spy point, you’d use the `'-'` predicate, not `pitch-name`).

If you want to see how any expression is processed by Prolog, use write\_canonical/1.

---

<div class="post-metadata">

**Author:** ![davidkettle](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/davidkettle/32/3669_2.png) [@davidkettle](https://swi-prolog.discourse.group/u/davidkettle)\
**Post date:** [August 19, 2021, 9:00pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/17 "2021-08-19T21:00:27Z")

</div>

He may have explained it very well, but unfortunately, I didn’t understand the explanation.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 20, 2021, 12:09am UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/18 "2021-08-20T00:09:21Z")

</div>

Did you understand my explanation? 😉

If you have any background in Lisp, you can think of Prolog “operators” as syntactic sugar for terms (e.g., `1+2` is just another way of writing `'+'(1,2)`) and everything is quoted by default, except for top-level goals in predicates. So, `1+2` doesn’t evaluate – it’s just a term; if you want it evaluated, you do something like `X is 1+2` (which is the same as `'is'('+'(1,2))`.  
Here’s another example:

```prolog
?- X = '+'(1,2). % Nothing is evaluated
X = 1+2.

?- X is '+'(1,2). % is/2 evaluates the term
X = 3.

?- Z = '+'(1,2), X is Z.
Z = 1+2,
X = 3.

```

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [August 20, 2021, 5:59am UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/19 "2021-08-20T05:59:22Z")

</div>

I didn’t explain it well at all 😉 I tried to give you something so that you can start figuring it out on your own.

As for predicate names, those must be valid atoms. You can always check if something is a valid atom using atom/1, like this:

```prolog
?- atom(pitch-name).
?- atom('Pitch name').
?- atom(pitch_name).
?- atom(Pitch_name).

```

(try those out on your toplevel!)

So you can, in fact, use quotes to put any text inside an atom.

Yet another issue is using predicate names that happen to be defined already. name/2 happens to be a built-in predicate. I try to avoid such name clashes so that I don’t have to look too far to know which predicate definition I will get. Note that a predicate is identified by its “predicate indicator”, so `Name/Arity` (with the forward slash). I prefer not to define predicates with the same name but different arity only, but it definitely has its uses. You will find plenty of examples of same name with different arities in the standard library, usually in the interface to a module.

To avoid any confusion here:

- Atoms defined as operators: feel free to reuse them. As long as they are just a part of a Prolog term, it depends on how you interpret that.
- Predicate indicators that are already used by built-in predicates (like name/2, atom/1, and so on): avoid redefining those predicates unless you know what you are doing. It is however perfectly fine to use the atom from the name inside your Prolog terms, so something like this is fine:

```prolog
my_pred(atom, foo).
my_pred(name, bar).

```

or even

```prolog
my_other_pred(atom/1, foo+2).
my_other_pred(name/2, bar+3).

```

---

<div class="post-metadata">

**Author:** ![davidkettle](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/davidkettle/32/3669_2.png) [@davidkettle](https://swi-prolog.discourse.group/u/davidkettle)\
**Post date:** [August 20, 2021, 1:18pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/20 "2021-08-20T13:18:55Z")

</div>

Yes, thanks.

---

<div class="post-metadata">

**Author:** ![davidkettle](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/davidkettle/32/3669_2.png) [@davidkettle](https://swi-prolog.discourse.group/u/davidkettle)\
**Post date:** [August 20, 2021, 1:29pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/21 "2021-08-20T13:29:52Z")

</div>

My mistake was in thinking that “pitch-name” would be parsed as a single token, as it would be in other languages I’m more familiar with, like C/C++, Java or Python. It was never my intention to redefine “name” or anything other predicate or operator. From now on, I’ll avoid using hyphens within names and use underscores instead. Knowing about write\_canonical/1 and atom/1 will also come in handy.

I’ve rewritten my code as follows (I added a second argument to print out more user-friendly names).

```prolog
pitch_name(c,'C').
pitch_name(cf,'Cb').
pitch_name(cs,'C#').
pitch_name(d,'D').
pitch_name(df,'Db').
pitch_name(ds,'D#').
pitch_name(e,'E').
pitch_name(ef,'Eb').
pitch_name(es,'E#').
pitch_name(f,'F').
pitch_name(ff,'Fb').
pitch_name(fs,'F#').
pitch_name(g,'G').
pitch_name(gf,'Gb').
pitch_name(gs,'G#').
pitch_name(a,'A').
pitch_name(af,'Ab').
pitch_name(as,'A#').
pitch_name(b,'B').
pitch_name(bf,'Bb').
pitch_name(bs,'B#').

```

Thanks.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 20, 2021, 5:13pm UTC](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309/22 "2021-08-20T17:13:08Z")

</div>

> [@davidkettle](#):
>
> thinking that “pitch-name” would be parsed as a single token, as it would be in other languages I’m more familiar with, like C/C++, Java or Python

If it’s inside quotes, then it’s a single name. You could, for example, write  
`'pitch-name'(c,'C')`, but that’s a bit clumsy, so people tend to not do it.

The only major programming language I know that allows hyphens inside names (as opposed to underscores) is COBOL. 😉

[Next page](https://swi-prolog.discourse.group/t/beginners-question-why-is-this-happening/4309.md?page=2)
