I would like to declare a data type in Mercury that can have a variable number of values and names. For instance :
type goal ---> pick; give; come.
has three variables/values.
I want something like:
type myplayer ---> de value declaration here.
That's the number of variables are not restricted or fixed.
So I can use myplayer to declare values/variables like v1, v2, v3 and v4. The second time I can use it to declare something like: a, b, c, d, e, z, aa, ab and az.
The number of the values are not restricted and the names are also not fixed.
I am new in Mercury.
As others have said, this is simply impossible in Mercury - which is deliberate.
What you might want though, if you want a type that expresses: v1 v2 v3... etc is:
:- type my_type
----> v(int).
:- func name(my_type) = string.
name(v(Num)) = formst("v%d", [i(Num)]).
The type expresses v of all integers, and the function name can be used to 'pretty-print' values of this type.
What you directly ask for, simply cannot be done. Given
:- type question
---> truth(string, bool)
; blank(string, string)
; multiple(string, string, list(string)).
additional kinds of questions can only be added by extending this type where it is defined, and recompiling the module - and making a lot of other changes, too, as previously deterministic code like
answer(truth(_, yes)) = "true".
answer(truth(_, no)) = "false".
answer(blank(_, A)) = A.
answer(multiple(_, A, _)) = A.
would fail when given your new question type. Being told at compile-time where you've failed to update your program to reflect the addition of a "pick-all-the-right-answers" type of question is a good part of the reason you have a question type at all, instead of say lists of strings [["Are foxes pretty?", "true"], ["Green foxes are ____", "adorable!", "fake", "evidence of animal cruelty"]] for your question bank.
What you ask for cannot be done. However, what you actually want to do -- the end to which you thought 'variable numbers of types' would be an helpful means -- can surely be accomplished in some other way. I can't tell what way that is, as I can't tell why you wanted to do this from your question. Maybe you'd benefit from reading over discriminated unions or typeclasses in the language reference.
As far as I understand this question. You want some Prolog-like behavior. I.e without typed predicates. In statically typed system you always can achieve such behavior by handling that by yourself. A lot of time ago I saw such example in Turbo Prolog (they implemented ISO prolog in terms of Turbo/Visual Prolog).
Consider something like (I'm not sure it is correct):
:- type any_type ---> atom_value(string)
; number_value(int)
; struct_value(any_type, list(any_type)).
guess(atom_value("v1")).
guess(atom_value("a")).
guess(atom_value("aa")).
guess(number_value(42)).
guess(struct_value(atom_value("pair"), [number_value(3), number_value(4)])).
Related
It is not uncommon to see data in Prolog written with a functor, e.g.
note("This is a note")
but Prolog can also process the data with the name moved to an argument, e.g.
(note,"This is a note")
When moving the data name from the functor into an argument, is there a name used to describe this process?
I have some code that will have the data converted as such and would like to include in the documentation a standard name to describe this change if it exist.
EDIT
The current specific reason for doing this is so I don't have to use =../2 and can also make comparison on many datum with anonymous variable, e.g.
(_,A,B,C)
or write more general predicates, e.g.
do(_)
do(_,A)
do(_,A,B)
instead of
do(note(A))
do(note(A,B))
do(note(A,B,C))
do(comment(A))
do(comment(A,B))
do(comment(A,B,C))
do(text(A))
do(text(A,B))
do(text(A,B,C))
EDIT
Below is a comment by #repeat with reasons not to do what is demonstrated in this question by changing a compound term note(A,B) into a comma list (A,B), as opposed to a regular list [A,B]. It is good advise but sometimes there are reasons for breaking such advise. I can not say at present for my current need if doing this in Prolog is one of those cases, but as the question asks, it would be nice to have a name for the process so that it can be searched for research.
#repeat You can edit this and add notes as it is all Creative Commons.
Actually, (note, "this is a note") is a term with functor , and arity 2 (first argument note, and second argument "this is a note").
You can see this issuing the following queries:
?- write_canonical(note("This is a note")).
note("This is a note")
?- write_canonical((note,"This is a note")).
','(note,"This is a note")
So what you are doing by "moving" the principal functor of a term of arity N to a term of arity N+1 with principal function , adding the previous functor name as the first argument and shifting the other arguments is some sort of generalization, though I don't know if there is a more suitable name for this.
You could see it as a restricted way to write an applicative encoding of a higher-order logic fragment into first order logic. An applicative encoding uses constants to represent functions and uses a binary function symbol app to express that f is applied to an argument list. For example, the applicative encoding of f(g(a),b) is app(f, [app(g,[a]),b ]). In your case, the ,/N operator plays this role but as you have probably noticed, without an argument list you need to know the number of arguments when you are matching against such a term.
An example where this encoding is used in a Prolog context is the higher-order automated theorem prover input format TPTP THF. They use an infix operator # to represent application. There, they also use the standard encoding which uses nested apps. The term representation is not as beautiful (the example term is written (f # (g # a))) # b) but it has the advantage that constants only have one representation. With the list encoding, you have to take into account that c = app(c, []).
Say I have a struct such as this:
flight( bos, nyc, time( 7,30 ) )
in the form of a variable: My_Flight.
If this variable was passed into a function like this:
my_func(Flight) :-
write(Flight[0])
How would I be able to extract the contents of the struct and do something with each part like the second line of the above function?
Sorry if my terminology is off, I'm pretty new to this language!
First, I recommend you think declaratively:
What must be the properties of such a struct in order for my_func/1 to hold?
Answer: For my_func/1 to hold, first, Flight must be of the form
flight(From, To, Time)
Using (=)/2 or, even better, direct pattern matching, we can already formulate this as a constraint on the argument:
my_func(flight(From,To,Time)) :-
...
You then state what else must hold about the arguments for my_func/1 to hold.
Do not think "how do I extract...", because the argument may not even be instantiated. Instead, ask: "What must hold about the argument?" This paves the way for many more usage modes: To extract, to construct, to check etc.
I hope this question is appropriate for this site, it's just about the choice of concrete syntax in Idris compared to Haskell, since both are very similar. I guess it's not that important, but I'm very curious about it. Idris uses => for some cases where Haskell uses ->. So far I've seen that Idris only uses -> in function types and => for other things like lambdas and case _ of. Did this choice come from realizing that it's useful in practice to have a clear syntactical distinction between these use cases? Is it just an arbitrary cosmetic choice and I'm overthinking it?
Well, in Haskell, type signatures and values are in different namespaces, so something defined in one is at no risk of clashing with something in the other. In Idris, types and values occupy the same namespace, which is why you don't see e.g. data Foo = Foo as you would in Haskell, but rather, data Foo = MkFoo - the type is called Foo, and the constructor is called MkFoo, as there is already a value (the type Foo), bound to the name Foo, e.g. data Pair = MkPair http://docs.idris-lang.org/en/latest/tutorial/typesfuns.html#tuples
So it's probably for the best it didn't try to use the arrow used to construct the type of functions, with the arrow used for lambdas - those are rather different things. You can combine them with e.g. the (Int -> Int) (\x => x).
I think it is because they interpret the -> symbol differently.
From Wikipedia:
A => B means if A is true then B is also true; if A is false then nothing is said about B
which seems right for case expressions, and
-> may mean the same as =>, or it may have the meaning for functions given below
which is
f: X -> Y means the function f maps the set X into the set Y
So my guess is that Idris just uses -> for the narrow second meaning, i.e. for mapping one type to another in type signatures, whereas Haskell uses the broader interpretation, where it means the same as =>.
parent(mel, joan).
parent(jane, betty).
parent(jane, tom).
parent(richard, adam).
parent(richard, rosa).
parent(joan, fran).
For example someone asks me to find all ancestors of a parent. I give him the code:
ancestor(P,C) :- parent(P, C).
ancestor(P,C) :- ancestor(P,P1), parent(P1, C).
But my friend still doesn't know how to use the predicate. Does he call it like
ancestor(richard, C) or ancestor(C, richard) ?
Is there a way to annotate that P is the parameter while C is the return value? And in a complex case, there will be predicates with different names, how should my user know which predicate is the final predicate he wants to use?
To help the human-readable meaning, you could add an extra predicate documenting the parameters as readable name/value pairs:
entry_ancestor_of(ancestor=P, descendent=C) :-
ancestor(P,C).
?- entry_ancestor_of(ancestor=richard, descendent=C).
C = adam .
Above, the suffix *ancestor_of* suggests param 1 is ancestor of param 2, so naming the predicate carefully can make it clearer.
Usually(convention), input parameters are the earlier parameters, and output parameters are later parameters, but where the predicate 'works both ways', ie. either could be input or output, this rule can't hold. This is the case for your predicate:
?- entry_ancestor_of(ancestor=X, descendent=adam).
X = richard .
Either parameter could be input or output, so there is no need to codify/explain them as such, although you might want to comment that it works both ways.
I would usually comment these 'flexible' predicates by putting an example of both of the above usages in a comment next to the predicate.
For entrypoint labelling, just do one or more of the following:
explicitly name the predicate as an entrypoint, as above
document using comments in the code which are the entrypoints
arrange the entrypoints in the same physical section with a comment
block saying that the predicates below are entrypoints.
Edit: Extra things re: coding guidelines / other answers.
In Coding guidelines for Prolog, section 3.8, it says 'For example, mother_of(A, B) is ambiguous;', so I gave bad advice on that.. perhaps acapelli's suggestion would be more useful on that.
In that document, also have a look at:
3.5 Choose sensible names for auxiliary predicates
3.8 Choose predicate names to help show the argument order
3.13 Decide whether predicate names should carry the types on which they operate
4.1 Begin every predicate (except perhaps auxiliary predicates) with an introductory comment in a well-defined format
The '?' system for identifying parameter types that will ness mentioned is on page 21.
a useful convention, sponsored for instance by Markus Triska, builds a predicate functor by joining the parameters 'names' - in a wide, applicable sense. Your example could be
parent_child(mel, joan).
...
ancestor_descendant(P, C) :- parent_child(P, C).
ancestor_descendant(A, D) :- ancestor_descendant(A, I), parent_child(I, D).
Also ISO-Prolog, and - for instance - SWI-Prolog library, attempt to follow this strategy.
For instance
atom_codes(Atom, Codes) :- ...
WRT to declare the type and status of arguments, some Prolog provide declarations - for instance Turbo Prolog, ECLiPSe, others... Sometime such declarations are required - usually to check correctness, often to speed up the computation.
SWI-Prolog offers 'just' structured comments, that IDE process automatically, and there has been a contribution aiming to exploit such declarations with runtime check.
Yes, with comments, and/or meaningful argument names,
% ancestor( ?Ancestor, ?Descendent).
ancestor(P,C) :- parent(P, C).
ancestor(P,C) :- ancestor(P,P1), parent(P1, C).
? means the argument can be used both as input (already set when the call is made), or for output (not yet set when the call is made).
The convention promoted in The Art of Prolog (I think) is that you place the name of the predicate after its first argument, to get at the intended argument ordering: P "is" ancestor C. Presumably "ancestor_of". But if you use that name, someone unfamiliar with that convention might read ancestor_of(P,C) as "ancestor of P is C", so it's a double-edged sword.
I am very new to Prolog and trying to learn.
For my program, I would like to have the user provide pairs of strings which are "types of".
For example, user provides at command line the strings "john" and "man". These atoms would be made to be equal, i.e. john(man).
At next prompt, then user provides "man" and "tall", again program asserts these are valid, man(tall).
Then the user could query the program and ask "Is john tall?". Or in Prolog: john(tall) becomes true by transitive property.
I have been able to parse the strings from the user's input and assign them to variables Subject and Object.
I tried a clause (where Subject and Object are different strings):
attribute(Subject, Object) :-
assert(term_to_atom(_ , Subject),
term_to_atom(_ , Object)).
I want to assert the facts that Subject and Object are valid pair. If the user asserts it, then they belong to together. How do I force this equality of the pairs?
What's the best way to go about this?
Questions of this sort have been asked a lot recently (I guess your professors all share notes or something) so a browse through recent history might have been productive for you. This one comes to mind, for instance.
Your code is pretty wide of the mark. This is what you're trying to do:
attribute(Subject, Object) :-
Fact =.. [Object, Subject],
assertz(Fact).
Using it works like this:
?- attribute(man, tall).
true.
?- tall(X).
X = man.
So, here's what you should notice about this code:
We're using =../2, the "univ" operator, to build structures from lists. This is the only way to create a fact from some atoms.
I've swapped subject and object, because doing it the other way is almost certainly not what you want.
The predicate you want is assertz/1 or asserta/1, not assert/2. The a and z on the end just tells Prolog whether you want the fact at the beginning or end of the database.
Based on looking at your code, I think you have a lot of baggage you need to shed to become productive with Prolog.
Prolog predicates do not return values. So assert(term_to_atom(... wasn't even on the right track, because you seemed to think that term_to_atom would "return" a value and it would get substituted into the assert call like in a functional or imperative language. Prolog just plain works completely differently from that.
I'm not sure why you have an empty variable in your term_to_atom predicates. I think you did that to satisfy the predicate's arity, but this predicate is pretty useless unless you have one ground term and one variable.
There is an assert/2, but it doesn't do what you want. It should be clear why assert normally only takes one argument.
Prolog facts should look like property(subject...). It is not easy to construct facts and then query them, which is what you'd have to do using man(tall). What you want to say is that there is a property, being tall, and man satisfies it.
I would strongly recommend you back up and go through some basic Prolog tutorials at this point. If you try to press forward you're only going to get more lost.
Edit: In response to your comment, I'm not sure how general you want to go. In the basic case where you're dealing with a 4-item list with [is,a] in the middle, this is sufficient:
build_fact([Subject,is,a,Object], is_a(Subject, Object)).
If you want to isolate the first and last and create the fact, you have to use univ again:
build_fact([Subject|Rest], Fact) :-
append(PredicateAtoms, [Object], Rest),
atomic_list_concat(PredicateAtoms, '_', Predicate),
Fact =.. [Predicate, Subject, Object].
Not sure if you want to live with the articles ("a", "the") that will wind up on the end though:
?- build_fact([john,could,be,a,man], Fact).
Fact = could_be_a(john, man)
Don't do variable fact heads. Prolog works best when the set of term names is fixed. Instead, make a generic place for storing properties using predefined, static term name, e.g.:
is_a(john, man).
property(man, tall).
property(john, thin).
(think SQL tables in a normal form). Then you can use simple assertz/1 to update the database:
add_property(X, Y) :- assertz(property(X, Y)).