Prolog: Recursion and splitting lists - recursion

I'm trying to write a game in which the program reads through a database, grabs attributes and asks the player if the Movie that the player is thinking of will have that attribute. The user will answer either yes or no and if yes, the game will ask about the next attribute until either the user has said yes to every attribute, at that point the program will output the name of the movie. Or if the user says no, the game will then move along to the next movie in the database and start asking about those attributes.
The game ends when either it finds a movie with all the attributes or there are no more movies in the database in which the program could ask about.
Here is the database file.
object_properties(crocodile_dundee,[comedy,australian,paul_hogan_movie]).
object_properties(flipper,[action_movie,australian, paul_hogan_movie,
-comedy]).
object_properties(jackass,[comedy,-australian]).
object_properties(the_godfather,[drama,crime,-character_batman]).
object_properties(the_dark_knight,[drama,crime,character_batman]).
object_properties(the_living_planet, [documentary,director_attenborough]).
object_properties(the_code, [documentary,nerds_love_it]).
object_properties(the_russian_revolution, [documentary,about_history]).
Here is my game file.
go():-
guess_object(0,[]).
guess_object(Obj,[A|As]) :-
object_categories(Obj,A).
guess_object(1).
guess_object(2).
guess_object(3).
guess_object(4).
guess_object(5). %how do i do this specifically for the current Obj attributes?
guess(X) :- guess_object(_, X),
writeln('Does your object have the attribute '(X)'?'),
read(Input), Input=('yes') -> assert(object(X)) ; retractall(X), guess(X).
writeln('I guess that the film is: 'guess_object(Obj,_).
The main questions I have:
How do I split the object attributes in to a list like I'm trying to do on guess_object(1) through to guess_object(5) depending on whether the object has 2 attributes or 4 attributes, etc.
How do I make my guess(A) predicate recursive so once the user says no it will then go to the next object in the database file?
I'm not too great at prolog but any advice or pointers would be greatly appreciated, even if it's just pointing out a stupid mistake I may have made. I will also answer any questions anyone has to the best of my ability.

Related

CosmosDB Ladder pattern

I'm reading this documentation https://blogs.msdn.microsoft.com/mvpawardprogram/2016/03/15/going-social-with-documentdb/ … it talks about a “Ladder pattern” but there are no examples and I can't seem to find this anywhere else. Could I get a little more direction on this concept?
I want to update all data duplicates with a pattern so i can update the main records and don't need to worry about it updating it everywhere its duplicated or reference.
You are looking at old documentation,
check the updated one on The “Ladder” pattern and data duplication
Let’s take user information as an example:
{
"id":"dse4-qwe2-ert4-aad2",
"name":"John",
"surname":"Doe",
"address":"742 Evergreen Terrace",
"birthday":"1983-05-07",
"email":"john#doe.com",
"twitterHandle":"#john",
"username":"johndoe",
"password":"some_encrypted_phrase",
"totalPoints":100,
"totalPosts":24
}
By looking at this information, we can quickly detect which is critical information and which isn’t, thus creating a “Ladder”:

Advice in Datadesign for nosql (firebase)

I'm new to the noSQL-Thing (I use firebase Realtime-Database for starters) and I'm writing a react-js app to manage Meetings and their Agenda Points.
The meeting has some attributes(name, planed duration, Start time, ... ) and the Agendaitems as well (name, planed duration, ... ).
So, my first intuition was to make a class Meeting with a Map of AgendaItems - but the Map doesn't get save in the firebase.
Then I tried a simple array - this works but I read "Arrays are bad in firebase"
So, whats the best strategy here? (I know that is probably a very Basic question)
And, would you put more "advanced" functions in the same Class? - e.g.: "nextAgendaItem", "addAgentaItem" to capsulate these implementation
or would you build a own "HandlerClass" witch has a Meeting as member

Watson Conversation: condition matching input to context array

Taking the car dashboard example, I altered the initial #genre node to be #genre:classical. I also added a list to the contex
"choices":["Beethoven","Mahler 9","Brahms 3rd"]
and the Watson response is "I have 3 selections". The condition on the next node is $choices.contains(input.text). The "Found a match" response is just for testing. It looks like this:
When I test this in the api tool and type "Beethoven" both "Found a match" and "Great choice!..." appear. Same for the other two choices, but only if I type the exact choice, e.g., "Mahler 9". Typing "Mahler" or "mahler" doesn't get a match. I read through the SpEL documentation but couldn't see a way in a one-line condition to parse through the list looking for partial matches.
So my question is, is there an condition expression that would match partial user input, e.g., "Mahler"? I'll be using the Java SDK to code the app server, so alternatively I wondered if I could add a temporary #entity just for this sequence instead of using the context list then delete it when the conversation is done? Or is there a way to construct a more complex condition in the MessageRequest and will Watson recognize it? Or is this just not the right way to go about this? Any pointers, examples or docs much appreciated.
So my question is, is there an condition expression that would match partial user input
You can't add temporary entities or intents. As adding them forces Watson to start training itself (even if you could it through code).
You can however create quite complex regular expressions, pass them in as a context variable.
For example your advanced node can have:
{
"output": {
"text": "Please ask me a question."
},
"context": {
"rx": "fish|[0-9]+"
}
}
Then in you condition you would write.
input.text.matches(context.rx)
This will then trigger if the person mentions a number, or the word fish. So you can create your partial user input checking that way.

Add custom text to AX 2012 drill-down links

I want to customize the standard drill-down functionality and add a text parameter to the drill-down URL. I will then parse and use the parameter in the SysStartUpCmdDrillDown or EventDrillDownPoller class like the solution provided by Jan B. Kjeldsen in this question.
The standard drill-down link is dynamics://Target/?DrillDown_RecID/ :
dynamics://0/?DrillDown_5637230378/
In previous versions of AX it was possible to modify the RecId to custom text and parse the text once the client is started:
dynamics://0/?DrillDown_0MenuItemName=PurchTable&FieldName=PurchId&FieldValue=P000044
Unfortunately, in AX 2012 the RecId is checked before the client is started and if it is not a valid int64, the drill-down event is not sent to the client. Since it is not possible to change the RecId to anything other than an integer, #Alex Kwitny suggested in the comments at that same question that you can add the custom text to the drill-down target like this:
dynamics://0MenuItemName=PurchTable/?DrillDown_5637230378/
The problem I experience with this is that the link now gets confused about which instance to start.
If the target is equal to the value in the System Admin -> system parameters -> Alerts ->Drill-down target, a client with the correct server instance is started. When I append the text with my custom text, it always starts the default instance(Which could be different from the instance I intended to start). While this is not ideal, I could work around this issue.
The bigger problem is that it now always starts a new session of the default instance, even if a client session is already started. As far as I can see I cannot write X++ code to solve this issue since the server instance is determined before any code in the client is executed.
My question is this - How can I add custom text to the drill-down link while preserving the way the client instance is started: If a client for the instance is already open, it should process the link in the open client, and not start up a new client of the default instance.
You should probably come up with another solution as mentioned in this post, but there could still be a way.
The URL has two objects that can be modified:
dynamics://[Drill-down target(str)]/?Drilldown_[Int64]
According to you, if you modify the [Drill-down target], then it launches AX using the default client config, and that is behavior that you don't want. If you have a matching [Drill-down target], it'll launch in the open client window, which is behavior I can't confirm, but I'll take it at face value and assume you're correct.
So that means the only thing you can modify in the URL is [int64]. This is actually a string that is converted to an int64 via str2int64(...), which in turn corresponds to a RecId. This is where it gets interesting.
This work all happens in \Classes\SysStartUpCmdDrillDown\infoRun.
Well, lucky for you the ranges for the objects are:
RecId - 0 to 9223372036854775807
Int64 - -9223372036854775808 to 9223372036854775807
You can call minRecId() and maxRecId() to confirm this.
So this means you have -9223372036854775808 to -1 numbers to work with by calling URLs in this range:
dynamics://0/?DrillDown_-1
to
dynamics://0/?DrillDown_-9223372036854775808
Then you would modify \Classes\SysStartUpCmdDrillDown\infoRun to look for negative numbers, and fork to your custom code.
HOW you decide to user these negative #'s is up to you. You can have the first n-digits be a table id or a look-up value for a custom table. You can't technically use a RecId as part of that negative number because in theory the RecId could get up that high (minus 1).

youtube channel new ID and iframe list user_uploads

It seems that youtube are now using ID's for their channels instead of names (part of the V3 api)
However it seems that the embedded iframe playlist player cannot handle these channel ID's
example channel https://www.youtube.com/channel/UCpAOGs57EWRvOPXQhnYHpow
then ID is UCpAOGs57EWRvOPXQhnYHpow
Now try to load this
http://www.youtube.com/embed/?listType=user_uploads&list=UCpAOGs57EWRvOPXQhnYHpow
Can anyone shine a light on this issue ? Or is there some hidden username ?
I also placed this question at the gdata-issues website http://code.google.com/p/gdata-issues/issues/detail?id=6463
The issue here is that a channel is not a playlist; channels can have multiple playlists, yet the listType parameter is designed to look for an actual playlist info object. The documented way around this is to use the data API and call the channel endpoint, looking at the contentDetails part:
GET https://www.googleapis.com/youtube/v3/channels?part=contentDetails&id=UCuo5NTU3pmtPejmlzjCgwdw&key={YOUR_API_KEY}
The result will give you all of the feeds associated with that channel that you can choose from:
"contentDetails": {
"relatedPlaylists": {
"uploads": "UUuo5NTU3pmtPejmlzjCgwdw"
}
}
If available (sometimes with oAuth), there could also be "watch later" lists, "likes" lists, etc.
This may seem like a lot of overhead. In the short term, though, it can be noted that the different feeds are programmatically named; so, for example, if my user channel begins with UC and then a long string, that UC stands for 'user channel' -- and the uploads feed would begin with 'UU' (user uploads) and then have the rest of the same long string. (you'd also have 'LL' for the likes list, 'WL' for the watch later list, 'HL' for the history list, 'FL' for the favorites list, etc. This is NOT documented, and so there's no guarantee that such a naming convention will perpetuate. But at least for now, you could change your ID string from beginning with UC to beginning with UU, like this:
http://www.youtube.com/embed/?listType=user_uploads&list=UUpAOGs57EWRvOPXQhnYHpow
And it embeds nicely.
Just to inform on current state of things -- the change suggested by jlmcdonald doesn't work anymore, but you can still get a proper embed link via videoseries (with the same UC to UU change). I.o.w. link like
http://www.youtube.com/embed/videoseries?list=UUpAOGs57EWRvOPXQhnYHpow
works as of at the moment of writing this.

Resources