How to use pointers in VP.

Discussions related to Visual Prolog
ahmednadi
VIP Member
Posts: 84
Joined: 15 Sep 2009 14:06

How to use pointers in VP.

Unread post by ahmednadi » 29 Apr 2012 11:43

Hi everybody;

Could you help me to know how can I use pointer or Jump to specific processing module?

Problem description: I have a very long predicate consists of 90 cases and each time the whole cases in the predicate should be tested sequentially to reached the right case which match the conditions and then the required processing done.

A lot of time consumption and many threads are done, please let me know if there is another method that can be used to go directly to the specific processing case like random access.

Thank you in advance.
_________________
AHMED NADY

User avatar
Thomas Linder Puls
VIP Member
Posts: 1622
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 29 Apr 2012 17:28

With 90 cases in a single predicate, it sounds like your code should be restructured.

Assume that we need to case on persons: child/adult and male/female; four cases in total.

We can do it like this:

Code: Select all

clauses     p(P) :- isChild(P), isMale(P), !, % Boy ....     p(P) :- isChild(P), not(isMale(P)), !, % Girl ....     p(P) :- not(isChild(P)), isMale(P), !, % Man ....     p(P) :- not(isChild(P)), not(isMale(P)), !, % Woman ....
To get to the Woman case, we will first calculate and fail in isChild in first clause, and then we will do exactly the same in second clause. I third clause we would again caluclate isChild, which again fails, but due to the not we will calculate isMail and fail. I fourth clause we calculate isChild and isMale once more.

This sounds similar to your description. But we can also do it like this:

Code: Select all

clauses     p(P) :- isChild(P), !, p_child(P).     p(P) :- p_adult(P).   clauses     p_child(P) :- isMale(P), !, % Boy ...     p_child(P) :- % Girl ...   clauses     p_adult(P) :- isMale(P), !, % Man ...     p_adult(P) :- % Woman ...
With this methode isChild and isMale is calculated exactly once each.
Regards Thomas Linder Puls
PDC

ahmednadi
VIP Member
Posts: 84
Joined: 15 Sep 2009 14:06

Unread post by ahmednadi » 30 Apr 2012 10:03

Hi Sir;

Thank you very much for your response.

I hope if you could help me with a more explanation of this case and a detailed example.

Best regards;

AHMED ANDY

User avatar
Thomas Linder Puls
VIP Member
Posts: 1622
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 30 Apr 2012 10:09

I think my description is absolutely clear and detailed :wink:.

So I think you should describe what it is that you think is unclear and/or undetailed.
Regards Thomas Linder Puls
PDC

ahmednadi
VIP Member
Posts: 84
Joined: 15 Sep 2009 14:06

Unread post by ahmednadi » 30 Apr 2012 12:25

Hi Sir;

Could you help me to know how can I use pointers?

I need to do something like GOTO.

I understand that I should split the 90 cases predicate to different predicates, but if it is failed in case, It should to call the next and the result will be the same as it is.

I need to make test that If I have a clause with a conjunction hence I will know the conjunction then I need to goto its processing module without access any other modules.

Thanks;

AHMED NADY.

User avatar
Thomas Linder Puls
VIP Member
Posts: 1622
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 30 Apr 2012 14:51

There is no such thing as GOTO in Visual Prolog.

However, if "processing" placed in a predicate then calling that predicate will "jump" directly to it.
... I should split the 90 cases predicate to different predicates, but if it is failed in case, It should to call the next and the result will be the same as it is.


You should notice that I have not made an arbitraty split.

I have used a divide and conquer method.

I first choose one of my tests (i.e. isChild) and divided the problem based on the possible outcomes of that test.

So instead of testing for isChild "here and there", I have made the test once and divided the original problem in two "halves" (i.e. p_child and p_adult), which never need to test for isChild again.

Hence the test is only performed once and there is no need for failing/backtracking.
Regards Thomas Linder Puls
PDC

Steve Lympany
VIP Member
Posts: 119
Joined: 31 Mar 2001 23:01

Unread post by Steve Lympany » 30 Apr 2012 18:14

Hi,
Or "another" way (sort of - I hope this is correct!) split your clause with 90 if/then/elses into 90 clauses (of the same predicate), with as much of the rule placed in the clause arguments.

The compiler will make a pointer to each clause, so if there is enough info in the clause arguments, processing will effectively make the "pointer jump" you want, ignoring all the clauses that don't satisfy the input arguments.

eg

Code: Select all

predicates      test:(integer,integer). clauses      mypred():-             test(4,7). clauses       test(1,1):-....       test(4,7):-.... (will jump straight to this - I think)
cheers
s

ahmednadi
VIP Member
Posts: 84
Joined: 15 Sep 2009 14:06

Unread post by ahmednadi » 1 May 2012 22:50


Steve Lympany
VIP Member
Posts: 119
Joined: 31 Mar 2001 23:01

Unread post by Steve Lympany » 2 May 2012 19:47

Hi,
I have given an example above. Maybe you should provide some of your if-then-elses, so that a more relevant example can be given (if it's possible)
cheers
s

dominique f pannier
VIP Member
Posts: 98
Joined: 23 Sep 2002 23:01

Unread post by dominique f pannier » 3 May 2012 17:24

Hi,
May be is it a simple problem of understanding.
Look at the little program below (a console one).

If you launch the predicate process1, you see that, when processing, like told Thomas, when you reach the predicate pred2 with its arguments, the new process which is executed is made by a jump where the right arguments are selected : the program automatically goes to the right process defined by these arguments.

If you launch the predicate process2, it does the same thing, but you can also, when you launch this predicate, decide what class of predicates belonging to the defined domain pred_dom you will use (in that example pred1 or pred2) : you can by this way extend the number of cases you have to handle.

Code: Select all

clauses     run():-         console::init(),         process1(1, 2, 3, 2, 1),         process2(1, 2, 3,  pred1, 1, 2),         _ = console::readline().     domains     pred_dom = (integer I1, integer I2) procedure (i,i).     class predicates     process1 : (unsigned A, unsigned B, unsigned C, integer I1, integer I2).     process2 : (unsigned A, unsigned B, unsigned C, pred_dom Pred, integer I1, integer I2).     p1 : (unsigned U).     p2 : (unsigned U).     p3 : (unsigned U). clauses   % The predicate <pred> is in the clause     process1(A, B, C, P1, P2):-         p1(A),         p2(B),         pred2(P1, P2),         p3(C).   % The predicate <pred> is a variable     process2(A, B, C, Pred, P1, P2):-         p1(A),         p2(B),         Pred(P1, P2),         p3(C).       p1(1):-!,         stdio::write("A\n)").     p1(_):-         stdio::write("nothing\n)").       p2(2):-!,         stdio::write("B\n)").     p2(_):-         stdio::write("nothing\n)").       p3(3):-!,         stdio::write("C\n)").     p3(_):-         stdio::write("nothing\n)").           class predicates     pred1 : pred_dom.     pred2 : pred_dom. clauses     % Process # 1         pred1(1, 1):-!,         stdio::write("hello John !\n").     pred1(1, 2):-!,         stdio::write("hello Carl !\n)").     pred1(_, _).   % Process # 2         pred2(2, 1):-!,         stdio::write("Hello Harriet !\n)").     pred2(2, 2):-!,         stdio::write("Hello Joy !\n)").     pred2(_, _).        
Does it help to solve your problem ?
Regards
Dominique Pannier

ahmednadi
VIP Member
Posts: 84
Joined: 15 Sep 2009 14:06

Unread post by ahmednadi » 4 May 2012 11:04

Hi Sir;
this is a part of the perdicate:

parser(i,i,o)

Code: Select all

parser(Sentence,WLst,POSList):- list::isMember ("as",WLst), list::isMember ("if",WLst), Index1 = list::tryGetIndex("as",WLst), Index2 = list::tryGetIndex("if",WLst), if Index1 <> 0 then SectionsLst=string::split_delimiter(Sentence,"as if"), my_main::sentTrim(SectionsLst,SecLst), stdio::writef("SecLst: %",SecLst), stdio::nl, pparse(SecLst,POSLst1), POSLst2=list::appendList(POSLst1), insertItem(POSLst2,Index1,"conj",POSLst3), insertItem(POSLst3,Index2,"conj",POSList) else SignPosition = search(Sentence, ","), string::front(Sentence, SignPosition, Begin, End), string::hasPrefix(Begin, "as if", Rest), SectionsLst=[Rest, End], stdio::writef("SectionsLst: %",SectionsLst), stdio::nl, pparse(SectionsLst,POSLst1), POSLst2=list::appendList(POSLst1), insertItem(POSLst2,Index1,"conj",POSLst3), insertItem(POSLst3,Index2,"conj",POSList) end if, if list::isMember ("0",POSList) then fail end if, stdIO::nl,!.   parser(Sentence,WLst,POSList):- list::isMember ("although",WLst), Index = list::tryGetIndex("although",WLst), stdio::writef("Index: %", Index),stdio::nl, if Index <> 0 then SectionsLst=string::split_delimiter(Sentence,"although"), my_main::sentTrim(SectionsLst,SecLst), stdio::writef("SecLst: %",SecLst), stdio::nl, pparse(SecLst,POSLst1), POSLst2=list::appendList(POSLst1), insertItem(POSLst2,Index,"conj",POSList) else SignPosition = search(Sentence, ","), string::front(Sentence, SignPosition, Begin, End), string::hasPrefix(Begin, "although", Rest), SectionsLst=[Rest, End], stdio::writef("SectionsLst: %",SectionsLst), stdio::nl, pparse(SectionsLst,POSLst1), POSLst2=list::appendList(POSLst1), insertItem(POSLst2,Index,"conj",POSList) end if, if list::isMember ("0",POSList) then fail end if, stdIO::nl,!.   parser(Sentence,WLst,POSList):- list::isMember ("though",WLst), Index = list::tryGetIndex("though",WLst), stdio::writef("Index: %", Index),stdio::nl, if Index <> 0 then SectionsLst=string::split_delimiter(Sentence,"though"), my_main::sentTrim(SectionsLst,SecLst), stdio::writef("SecLst: %",SecLst), stdio::nl, pparse(SecLst,POSLst1), POSLst2=list::appendList(POSLst1), insertItem(POSLst2,Index,"conj",POSList) else SignPosition = search(Sentence, ","), string::front(Sentence, SignPosition, Begin, End), string::hasPrefix(Begin, "though", Rest), SectionsLst=[Rest, End], stdio::writef("SectionsLst: %",SectionsLst), stdio::nl, pparse(SectionsLst,POSLst1), POSLst2=list::appendList(POSLst1), insertItem(POSLst2,Index,"conj",POSList) end if, if list::isMember ("0",POSList) then fail end if, stdIO::nl,!.
Your fast action will be highly appreciated.
AHMED

Steve Lympany
VIP Member
Posts: 119
Joined: 31 Mar 2001 23:01

Unread post by Steve Lympany » 4 May 2012 12:01

Hi,

I think you will not gain much of a speed increase from restructuring (=breakin the clause down). It may enhance readability, and ease maintainability.

What I had assumed that you had was one if-block i.e.

if then elseif elseif elseif........endif

with 90 elseifs. You say "90 cases"...? I only see, mainly, only "if Index<>0"

cheers
s

ahmednadi
VIP Member
Posts: 84
Joined: 15 Sep 2009 14:06

Unread post by ahmednadi » 4 May 2012 16:11

Hi Sir;

Thank you for you reply.

Could you help me to implement this part of code by using argument to be as pointer.
The idea which you spoke about.

Regards;
AHMED NADY

Steve Lympany
VIP Member
Posts: 119
Joined: 31 Mar 2001 23:01

Unread post by Steve Lympany » 4 May 2012 17:09

Hi,
Sorry, I don't know what you mean or want. As you said at the beginning, the whole clause is sequential. Which part of the clause to you want to "jump" from and to?

regards
s

Harrison Pratt
VIP Member
Posts: 283
Joined: 5 Nov 2000 0:01

Re:

Unread post by Harrison Pratt » 4 May 2012 19:08

By "pointer" do you mean a number that refers to a location of a data structure in memory, or do you mean the "pointer" is an index to the current position in the Sentence being processed by your clause?
ahmednadi wrote:Hi Sir;

Thank you for you reply.

Could you help me to implement this part of code by using argument to be as pointer.
The idea which you spoke about.

Regards;
AHMED NADY

Post Reply