3 ms·
There are several ways to do it. One straight-forward way is as follows: We can represent comments by facts like: comment_id_user_text_points(3, 1, 'hello
by zmonx 9y ago
There are several ways to do it. One straight-forward way is as follows:
We can represent comments by facts like:
comment_id_user_text_points(3, 1, 'hello!', []).
I do not know what exactly you mean by "points", so I have simply supplied an empty list (fourth argument) in this case. Note that there is an ID for the comment, and an ID for the user that posted the comment. Therefore, we say that this is a relation between users and comments and their text and points, usable in all directions.
Each user can likewise be represented as follows, relating a unique ID to a name and e-mail address:
user_id_name_email(1, 'randomUser1122', [random,'ycombinator.com']).
For admins, I can simply add additional facts, relating user IDs to rights like this:
admin_id_rights(1, [delete,hide]).
Now, we can simply post queries over these facts, such as:
?- user_id_name_email(ID, _, _),
comment_id_user_text_points(_, ID, Text, _).
and obtain, on backtracking, all comments for any user.
This is all completely analogous to how you would represent such data in any database system. It's more convenient in Prolog though for several reasons.
- randomUser1122 9y agoWow, modelling it like in a relational DB is a great idea! Thanks. Your trick of adding names of the properties like "_id_user_text" is neat. In the past, I tried a similar solution like but I would always forget which property is at which position. How would you make sure that the rights of admins are only delete, hide, and modify (and not e.g. walk, talk, chalk) ? If I use admin_id_rights(Id, Rights):- numeric(ID), sort(Right, SortedRights), subset(SortedRights, [delete, hide, modify]). , then I obviously have added all possible admins. Moreover, how would you then 'create' objects without adding them with asserta. Assume that all the user, admins, comments are written to a text file which should be queried. I can easily read them into some nested compounds with DCGs. However, I would like to create objects(e.g.like Java's new) to check that they adhere to the contraints of my model.
- zmonx 9y agoThe naming trick makes clear what each position means: The order of arguments follows that of the name's components. So, if the name contains id_user_text, then the arguments are also in this order: ID of comment, ID of user, and the text. This is a simple mnemonic technique I use for naming important predicates. As to your first question, we are now talking about (database) integrity constraints. So I would first state which rights are admissible at all by clearly defining what we consider a right. For example, in this concrete case: right(delete). right(hide). right(modify). Next, I describe the situation that an admin was inadvertently assigned a "bad" (i.e., not actually existing) right: user_bad_right(ID, R) :- admin_id_rights(ID, Rs), member(R, Rs), \+ right(R). Now, I can ask Prolog: Are there any bad rights assigned? I do this by simply posting the most general query about this relation: ?- user_bad_right(ID, R). false. I conclude: No, there are no bad rights assigned. As for creating objects: This is a good case of using the dynamic database, i.e., predicates like assert/1 and assertz/1. The database is very good for frequently retrieving information, but not good for frequently updating the information. This is a fitting situation: Comments are presumably only posted once, and in that case, you can simply add such facts to the database. But you can of course also make all this explicit, and first construct a term of the form comment_id_user_text_points(3, 1, 'hello!', []), and then reason about such terms (instead of reasoning about the asserted facts). Note that this term looks exactly like the fact syntactically, due to the homoiconic nature of Prolog. Therefore, you have many ways to reason about your data. You can even write all such terms to an external file, and simply consult all facts (and even rules) it contains by invoking consult/1 dynamically.
- randomUser1122 9y agoThank you for all you great tips. Do you know any good book(except Craft of Prolog, Prolog for AI) or good code on github following this principle?
- zmonx 9y agoThank you for your interest! Since Prolog is now gaining more traction, I am adding to my favourites all Prolog links which I consider noteworthy or recommended reading. Please see my profile for more information, and also for future updates.
- kabowen 9y agoOn GitHub, you may want to check out https://github.com/AppliedLogicSystems/ALSProlog https://github.com/AppliedLogicSystems/ALSProlog