# Line number (and file name) of fact read

**URL:** <https://swi-prolog.discourse.group/t/line-number-and-file-name-of-fact-read/1228>\
**Category:** Help!\
**Created:** [September 11, 2019, 3:27am UTC](https://swi-prolog.discourse.group/t/line-number-and-file-name-of-fact-read/1228 "2019-09-11T03:27:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [September 11, 2019, 3:27am UTC](https://swi-prolog.discourse.group/t/line-number-and-file-name-of-fact-read/1228/1 "2019-09-11T03:27:29Z")

</div>

Hello,

I am using term expansion to create a Domain Specific Language (DSL).

For example, keyword(X) gets expanded to dsl(keyword(X)).

A failure driven loop then reads each keyword in sequence:

```prolog
process :-
    dsl(X),
    process(X),
    fail.

```

process.

Is there a way to determine the line number in the file in which the fact dsl(X) appears on the file?

I’d like to use is to report syntax or semantic errors …

E.g. what I want to write out after reading dsl(keyword(arg)) on line 5 in file trial.pl

```prolog
Warning': keyword(arg) in line 5 of file: trial.pl - expected arg2 instead. 

```

Can this be done?

Thanks,

Dan

---

<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:** [September 11, 2019, 4:21am UTC](https://swi-prolog.discourse.group/t/line-number-and-file-name-of-fact-read/1228/2 "2019-09-11T04:21:38Z")

</div>

Does this help?

```prolog
?- read_term(Z, [subterm_positions(X), term_position(Y)]).
|: foo(a,[1,2,3]).

Z = foo(a, [1, 2, 3]),
X = term_position(666, 680, 666, 669, [670-671, list_position(672, 679, [673-674, 675-676, 677-678], none)]),
Y = '$stream_position'(666, 30, 0, 666).

?- [user].
|: foo(a, [1,2,3]).
|: ^D% user://1 compiled 0.00 sec, 1 clauses
true.

?- predicate_property(foo(_,_), Property), writeln(Property), fail; true.
interpreted
visible
static
file(user://1)
line_count(37)
number_of_clauses(1)
number_of_rules(0)
last_modified_generation(23889)
defined
true.

```

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [September 11, 2019, 4:26am UTC](https://swi-prolog.discourse.group/t/line-number-and-file-name-of-fact-read/1228/3 "2019-09-11T04:26:00Z")

</div>

Thank you.

> [@grossdan](#):
>
> ```prolog
> process :-
> dsl(X),
> process(X),
> fail.
> 
> ```

So, this means I would do something like that:

```prolog
process :-
    read_term(dsl(X), term_position(Y)),
    writeln(Y),
    process(X),
    fail.

```

process.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [September 11, 2019, 5:46am UTC](https://swi-prolog.discourse.group/t/line-number-and-file-name-of-fact-read/1228/4 "2019-09-11T05:46:26Z")

</div>

See [https://www.swi-prolog.org/pldoc/doc\_for?object=prolog\_load\_context/2](https://www.swi-prolog.org/pldoc/doc_for?object=prolog_load_context/2)

---

<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:** [September 11, 2019, 7:19am UTC](https://swi-prolog.discourse.group/t/line-number-and-file-name-of-fact-read/1228/5 "2019-09-11T07:19:05Z")

</div>

See [clause\_property/2](https://www.swi-prolog.org/pldoc/man?predicate=clause_property/2). As long as the clause was produced with [term\_expansion/2](https://www.swi-prolog.org/pldoc/man?predicate=term_expansion/2) in a normal load this will give the file and line for each clause. See also [clause\_info/5](https://www.swi-prolog.org/pldoc/doc_for?object=prolog_clause%3Aclause_info/5), although that may require some additional rules if the clause has been transformed.
