1

I have facts stored in different formats f.e.:

 fact(a,b,c)
 fact(d,e,f(g,h))
 fact(j(k,l),m,n(o,p,q))
 ...

.. always triple. I want to create a VIEW of the facts by only seeing the functor i.e.

 fact(a,b,c)
 fact(d,e,f)
 fact(j,m,n)
 ...

how do you do that .. ?

.. of course i want to be able to query them as normal facts ... omitting the hidden structure of-course (it will be interesting to take the hidden structure into account, but lets not complicate things for now)

PS> In general the most important thing is that the fact is a triple .. in the future I may change the possible structure of the items, but I want to be able to have simplified views where it is a triple. Any ideas along these lines are welcome.

sten
  • 7,028
  • 9
  • 41
  • 63
  • Vocabulary detail: "functor" --> "functor name". The "functor" is ["an identifier together with an arity"](https://stackoverflow.com/questions/49898738/is-this-prolog-terminology-correct-fact-rule-procedure-predicate) i.e. "name/arity" (as per ISO Standard definition). So you really want to see the (functor or predicate or function) _identifier_ or _name_ – David Tonhofer Dec 21 '20 at 21:12

2 Answers2

3
factview(fact(A, B, C)) :-
    fact(Af, Bf, Cf),
    functor(Af, A, _),
    functor(Bf, B, _),
    functor(Cf, C, _).

Gives

?- factview(X).
X = fact(a, b, c) ;
X = fact(d, e, f) ;
X = fact(j, m, n).
rajashekar
  • 3,460
  • 11
  • 27
2

A more generic approach for SWI-Prolog:

fact(a,b,c).
fact(d,e,f(g,h)).
fact(j(k,l),m,n(o,p,q)).

view(Predicate/Arity) :-
    functor(Head, Predicate, Arity),
    forall( clause(Head, true),
            ( compound_name_arguments(Head, Predicate, Arguments),
              maplist([A,F]>>functor(A,F,_), Arguments, Functors),
              compound_name_arguments(Fact, Predicate, Functors),
              writeln(Fact) ) ).

Query:

?- view(fact/3).
fact(a,b,c)
fact(d,e,f)
fact(j,m,n)
true.
slago
  • 5,025
  • 2
  • 10
  • 23
  • This is good. Might need to make it dynamic, and assert the facts to query them. – rajashekar Dec 21 '20 at 18:24
  • @rajashekar Yes! You can call ```assertz/1``` instead of ```write/1```! – slago Dec 21 '20 at 18:28
  • @rajashekar Or you can, alternatively, get ```Fact``` by adding it as a second argument for predicate ```view/2``` (and also by removing the call to ```forall/2```). – slago Dec 21 '20 at 18:30
  • Yes, `clause` backtracking should get all of them. That would be a better solution. – rajashekar Dec 21 '20 at 18:35