FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister   ProfileProfile   Log inLog in 


Extending the sample Visual Prolog sample Calendar code to use FACTS

Post new topic   Reply to topic    discuss.visual-prolog.com Forum Index -> Visual Prolog
View previous topic :: View next topic  
Author Message
larryhoughton



Foothill Ranch
Joined: 04 Oct 2016
Posts: 9

PostPosted: 16 Aug 2017 7:06    Post subject: Extending the sample Visual Prolog sample Calendar code to use FACTS Reply with quote

Hello,
I'm trying to extend the sample Visual Prolog sample Calendar code to use FACTS instead of creating the Calendar "Event" data within the code (i.e. hard coded Calendar Events).

I'm looking for guidance on the best Prolog coding strategy (i.e. commands) to make the Calendar sample code read Calendar Event data from a set of Prolog Facts. Later I'll be pulling the Facts from a MS SQL Server DB. Ideally I would want to separate the data retrieval code out to another class as the Family4 sample code explains.

The way that I'd like to create the json object (see my code below) is syntactically incorrect and all my attempts to make it syntactically correct produce a cornucopia of other errors that I'm sure would be easy to fix if I knew what I was doing.

Errors such as:
    A foreach loop must be a Procedure (so you can't retrieve Facts within the Foreach)
    My json Value isn't compatible with my json Object (Probably something to do with the 'o' in the sample code that I can't figure out to recreate in my code)
    Struggles with keeping my Procedure/Determ/Nondeterm constrictions all in alignment
So long story short, I could really use some help. What would be the best way to modify the Calendar Sample Code to read "Events" from a set of Facts and still produce the json object for the website to retrieve?
Thanks for your patients...

Original Calendar Sample Code Snippet (Which I want to modify to use FACTS)

predicates
    calendar : jsonProc_name.
 clauses
    calendar(_Context, ArgMap) = o(Result) :- % Where 'o' is defined and what it is does is a separate mystery to me.
        Result = jsonObject::new(),
        Email = ArgMap:get_string("emailaddr"),
        MyEvents = [
           o(mkEvent("Lunch",  mkTime(1, 11, 15), mkTime(1, 14, 45),"30"),true),
           o(mkEvent("Dinner", mkTime(-1, 10, 30),mkTime(2, 11, 00),"40"),true)
   ],
        Result:set_array("events", MyEvents).

My failing "getEvents()" code
Below is the simplest representation of the code that I wish would work. However it cannot work as written because it is syntactically incorrect and I'm pretty sure I need some help with json Values Vs json Objects syntax.

predicates
    getEvents : () -> jsonObject V.
clauses
getEvents() = (Result) :-
        Result=jsonObject::new(),
   MyEvents = [  
        foreach events(Title, Start, End, Resource,AllDay) do
      V=mkEvent(Title, Start,End, Resource,AllDay)
   end foreach]

Everything below here is for reference only

"initEventFacts()"
Creates the Facts to Read (this works fine)

predicates
    initEventFacts : ().
clauses
initEventFacts():- % Save two Facts (This clause is working fine)
   assert(events("My Facts Row 1", mkTime(1, 11, 15), mkTime(1, 14, 45),"30",true)),
   assert(events("My Facts Row 2", mkTime(-1, 10, 30),mkTime(2, 11, 00),"40",true)).

"MkEvent Code"
Unmodified Calendar Sample Code (used by me above and the original sample code)

predicates
    mkEvent : (string Title, string Start, string End, string Resource, boolean AllDay)  -> jsonObject V.
clauses
    mkEvent(Title, Start, End, Resource, AllDay) = V :-
        V = jsonObject::new(),
        V:set_string("title", Title),
        V:set_string("start", Start),
        V:set_string("end", End),
        V:set_string("resource", Resource),
        V:set_boolean("allDay", AllDay).

Back to top
View user's profile Send private message
Thomas Linder Puls



Copenhagen, Denmark
Joined: 28 Feb 2000
Posts: 3104

PostPosted: 16 Aug 2017 10:19    Post subject: Reply with quote

Let us start with the 'o'. It comes from the domain json::jsonValue (here with an extended domain description):

class json
...
domains
    jsonValue =
        n;
        f;
        t;
        r(real Number);
        s(string String);
        a(jsonValue* Array);
        o(jsonObject Object) [presenter(presenter_jsonValue)].
    % @short Represent the JSON values corresponding to the ECMA 404 standard.<br>
    % n - the JSON constant null<br>
    % f - the  JSON constant false<br>
    % t - the  JSON constant true<br>
    % r(Number) - a JSON number<br>
    % s(String) - a JSON string String<br>
    % a(Array) - a JSON array as a list <br>
    % o(Object) - a JSON object<br>
    % See also http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
    % @end
...

See alsoAs you can see a JSON value is one of 7 things, a JSON object being one of them. A JSON object is represented by a jsonObject and packed in the json::o functor in our representation.

regarding 'foreach'. foreach does not produce any value(s), what you need is a list comprehension which produces a list from a nondeterministic iteration:

MyEvents = [ mkEvent(Title, Start,End, Resource,AllDay) || events(Title, Start, End, Resource, AllDay) ]

However, I think it you should avoid/minimize data caching in your application. I.e. instead of loading data into facts and then serve them from the facts, you should rather serve them directly from the database. The layer structure from the family4 example is a good idea. Your Web service layer will use with a business layer which will use a data layer which will use the SQL database.

class myCalendarWebService : rpcService

constructors
    new : (myCalendarBL CalendarBL).

end class myCalanderWebService


implement myCalendarWebService inherits jsonRpcServiceSupport

facts
    calendarBL : myCalendarBL.

clauses
    new(CalendarBL) :-
        calendarBL := CalendarBL,
        setProc_name("calendar", calendar).

class predicates
    calendar : jsonProc_name.
clauses
    calendar(_Context, ArgMap) = o(Result) :-
        Email = ArgMap:get_string("emailaddr"),
        Events = calendarBL:getEvents_email(Email),
        Result = jsonObject::new(),
        EventsJson = [ mkJsonEvent(E) || E in Events ], % transform prolog events to JSON events
        Result:set_array("events", Events).

....


_________________
Regards Thomas Linder Puls
Prolog Development Center
Back to top
View user's profile Send private message
larryhoughton



Foothill Ranch
Joined: 04 Oct 2016
Posts: 9

PostPosted: 19 Aug 2017 3:19    Post subject: Reply with quote

Okay, I've conquered my aforementioned json 'o' and Procedure issues with your help, thank you. And I have the sample ODBC code working with an MS SQL DB. What I can't put together now is how the results from an SQL query become available for goal processing. That is, with a Fact I can simply resolve all of the Events with something like:

events(Title,StartTime,EndTime,Resource) % Where none of the variables are bound

And with a Fact, I can do backtracking and all the things that make Prolog great.
With SQL I can retrieve the same fields with something like:

Select Title,StartTime,EndTime,Resource from Events

But how do I retrieve the data in such a way that I can use Prolog logic like backtracking, etc?, For reference, up to now I thought the answer was to retrieve the field data with SQL and assert it into Facts.

For future readers of this thread, here are the modifications I made to the Calendar sample code to use Facts ....
The big breakthrough was using the suggestion (see this thread) to stop using the foreach loop and instead use list comprehension:

MyEvents = [ mkEvent(Title, Start,End, Resource,AllDay) || events(Title, Start, End, Resource, AllDay) ]

My version only deals with the one type of Event (shown above).


predicates
    calendar : jsonProc_name.
clauses
    calendar(_Context, ArgMap) = o(Result) :-
    Result= mkEvent(). % Removed everything else for my test

predicates
   mkEvent : () -> jsonObject V.
clauses % Creates a new class object "MyEventData"
    mkEvent() = V :-
    MyEventData=data::new(),
    MyEventData:initEventFacts(),  %  Asserts some Event Facts
    V=MyEventData:getEvents().    % Retrieves the Event Facts into "V" a json object

/* Retrieves all of the Events from the asserted Facts */
predicates
    getEvents : () -> jsonObject V.
 getEvents() = Result :-
        Result=jsonObject::new(),
        MyEvents = [ o(mkEvent(Title, Start,End, Resource,AllDay)) || events(Title, Start, End, Resource, AllDay) ], % This command loads up all of the Events into an Array "MyEvents".  Note the 'o' before mkEvent
        Result:set_array("events", MyEvents),
        R30 = mkResource("30", "Facts DB Larry"),
        R30:set_string("email", "SomeEmail@cox.net"),
        Result:set_array("resources", [o(R30)]).

Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    discuss.visual-prolog.com Forum Index -> Visual Prolog All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum