Database manipulation
Sponsored Links
This presentation is the property of its rightful owner.
1 / 44

Database Manipulation PowerPoint PPT Presentation


  • 99 Views
  • Uploaded on
  • Presentation posted in: General

Database Manipulation. Section 7.4. Prolog Knowledge Base. Knowledge base = database set of facts/rules in the program Can add/subtract facts and rules at run time Adding facts/rules assert, asserta, assertz Subtracting facts/rules retract, retractall. Asserting a Fact.

Download Presentation

Database Manipulation

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Database Manipulation

Section 7.4


Prolog Knowledge Base

  • Knowledge base = database

    • set of facts/rules in the program

  • Can add/subtract facts and rules at run time

  • Adding facts/rules

    • assert, asserta, assertz

  • Subtracting facts/rules

    • retract, retractall


Asserting a Fact

  • Just tell prolog that it’s so

    ?- raining.

    ERROR: Undefined procedure: raining/0

    ?- assert(raining).

    Yes

    ?- raining.

    Yes

  • Prolog didn’t know about raining/0


Preparing Prolog for a Predicate

  • Need to tell Prolog that the predicate exists

    • helpful also to say that it may have rules added

  • Give a directive in the program file

    • a command to Prolog

      :- dynamic raining/0.

  • Says that raining/0 is a predicate

    • prevents the error message


Dynamic Predicates

  • Can be done during session

    ?- dynamic foggy/0.

    Yes

    ?- foggy.

    No

  • Note how we call goals in a file

    :- dynamic foggy/0.

    • can do that with any query


Asserting Rules

  • Just give rule instead of fact

    • use parentheses if rule is compound (to prevent confusion about the comma)

      ?- assert(raining).

      ?- assert(bad :- raining ; foggy).

      ?- assert(nice :- (sunshine, \+ cold)).

      ?- bad.

      Yes


Assertion Order

  • assert/1 puts the fact/rule in the database

    • order is implementation dependent

    • (SWI-Prolog puts it at the end)

  • asserta/1 puts fact/rule in front

  • assertz/1 puts fact/rule at end


Assertion Order

?- assert(num(1)).

?- assertz(num(2)).

?- asserta(num(0)).

?- assertz(num(3)).

?- num(X).

X = 0 ;

X = 1 ;

X = 2 ;

X = 3

Adds num(1) to database

Adds num(2) to end of DB

Adds num(0) to front of DB

Adds num(3) to end of DB

num(0).

num(1).

num(2).

num(3).


Assertion Order Exercise

?- asserta(what(1)).

?- assertz(what(2)).

?- asserta(what(3)).

?- assertz(what(4)).

?- asserta(what(5)).

?- what(X).

X = ? ;

X = ? ;

X = ? ;


Exercise

  • Write a predicate that asks the user for a person’s parents & asserts those facts

    ?- add_parents(mark).

    Who is mark’s father? bob.

    Who is mark’s mother? isabel.

    Yes

    ?- father(mark, Dad), mother(mark, Mom).

    Dad = bob, Mom = isabel


Solution

ask_parents(Person) :-

ask_for_who(Person, father, Dad),

ask_for_who(Person, mother, Mom),

assert(father(Person, Dad)),

assert(mother(Person, Mom)).

ask_for_who(Person, Role, Name) :-

write(‘Who is ’), write(Person), write(‘\’s ’),

write(Role), write(‘? ’), read(Name).


Retraction

  • Tell Prolog to remove a fact/rule

    ?- raining.

    Yes

    ?- retract(raining).

    Yes

    ?- raining.

    No


Retracting Rules

  • As for asserting rules

    • use parentheses if body is compound

    • body may be a variable/partly instantiated

      ?- retract(bad :- raining ; foggy).

      ?- retract(nice :- Body).

      Body = sunshine, \+ raining

      Yes


Retraction Order

  • From first to last

    ?- retract(num(N)), retract(num(M)).

    N = 0

    M = 1

    Yes

  • retract fails if no clause matches


Retracting All Clauses

  • rectractall/1 retracts multiple clauses

    • all clauses with head matching the argument

      ?- num(N).

      N = 0

      ?- retractall(num(N)).

      Yes

      ?- num(N).

      No

Note:also gets rules

?- assert(bad :- member(1,[1])).

Yes

?- bad.

Yes

?- retractall(bad).

Yes

?- bad.

No


Asserting and Retracting

  • Used for AI programs that learn

    • create a new rule & add it to the database

    • forget an old rule

  • Can also be used for efficiency

    • asserta solutions previously found

    • found before general code called


Naïve Fibonacci

fib(1, 1).

fib(2, 1).

fib(N, F) :-

N > 2,

N1 is N – 1, fib(N1, F1),

N2 is N – 2, fib(N2, F2),

F is F1 + F2.


Trace fib(5,F)

fib(5, F0)

fib(4, F1)

fib(3, F2)

fib(2, F3)  F3 = 1

fib(1, F4)  F4 = 1

fib(2, F5)  F5 = 1

fib(3, F2)

fib(2, F3)  F3 = 1

fib(1, F4)  F4 = 1

fib(3, F) gets calculated again

extra work done

much worse as #s get bigger


Assertional Fibonacci (8.5.4)

fib2(1, 1).

fib2(2, 1).

fib2(N, F) :-

N > 2,

N1 is N – 1, fib2(N1, F1),

N2 is N – 2, fib2(N2, F2),

F is F1 + F2,

asserta( fib2(N, F) ).% remember the result

% at the beginning


Trace fib2(5,F)

fib2(5, F0)

fib2(4, F1)

fib2(3, F2)

fib2(2, F3)  F3 = 1

fib2(1, F4)  F4 = 1

asserta( fib2(3, 2) )

fib2(2, F5)  F5 = 1

asserta( fib2(4, 3) )

fib2(3, F6)  F6 = 2

asserta( fib2(5, 5) )

Saves work from calculating fib(3)

Matches asserted fact – no need to recalculate


Problems for Asserting Solutions

  • Backtracking gives multiple solutions

    • saved solution found first

    • then solution re-calculated

    • and re-asserted: solution there twice, now

    • next time there’ll be three solutions

  • Adding a cut to the solution might help

    • asserta( fib2(F, N) :- ! ).


Generating Facts

  • Multiplication table

    make_table :-

    \+ (L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

    member(X, L),

    member(Y, L),

    Z is X * Y,

    assert(product(X, Y, Z)),

    fail).


Using the Multiplication Table

  • Now have 100 multiplication facts

    ?- product(X, Y, 12).

    X = 2, Y = 6 ;

    X = 3, Y = 4 ;

    X = 4, Y = 3 ;

    X = 6, Y = 2 ;

    No


Asserts on Calls in Progress

  • Suppose assert or assertz a clause of a predicate that’s in progress

    • is that clause considered for that call?

      strange(N) :-

      assertz(strange(N)),

      fail.

  • Does strange(3) succeed or fail?

    • or throw an exception


Speed of Dynamic Predicates

  • Dynamic predicates may be slower than static (dynamic = can change, static = can’t)

  • Prolog may have a better way for remembering solutions

    • remember or record predicates to memorize

    • recall or recorded to recall

    • forget or erase to forget


Remembering Solutions

  • One clause (near front) to look for remembered solutions

    • cut if find one

  • Remember solution after it’s calculated


Remembering Fibonacci

fib_mem(0, 1).

fib_mem(1, 1).

fib_mem(N, F) :- recorded(fibonacci, fib(N, F)), !.

fib_mem(N, F) :-

N > 1,

succ(N1, N),fib_mem(N1, F1),

succ(N2, N1),fib_mem(N2, F2),

F is F1 + F2,recorda(fibonacci, fib(N, F)).


Recording

  • recorda/2, recordz/2 store 2nd argument

    • use 1st argument as a key

    • you can record same fact under multiple keys

    • key is integer or atom (or term – but no good)

  • recorded/2 retrieves fact

    • needs key – only retrieves facts under that key

    • matches fact – only those that match selected


Erasing/Forgetting

  • recorded/3 also gives a memory location

  • Can use the location to erase the record

    ?- recorded(fibonacci, fib(500,_), Mem),

    erase(Mem).

    Yes

  • Can only erase one item at a time

    • don’t erase anything more than once


Versions of Fibonacci

  • Vanilla version is very slow

    • and only works on a few numbers

  • Remembering version quite fast

    • even faster when asking a second time

  • Single recursion version very fast

    • but second time takes as long as first

      ?- time(fib(20, F)), time(fib2(20, F)), time(fib_mem(20, F)).


Looking at Code

  • Program can inspect its own code

  • clause/2 returns clauses of program

    • 1st argument is the head of the rule

    • 2nd argument is the body

    • at least one argument must be given


Clause/2

sibs(Sib1, Sib2) :-parent(Sib1, P), parent(Sib2, P),

different(Sib1, Sib2).

different(X, Y) :- X \= Y.

?- clause(sibs(_, _), Body).

Body = parent(_1,_2), parent(_3,_2), different(_1,_3)

?- clause(Head, _A \= _B).

Head = different(_1,_2)

Note: this last one doesn’t seem to work in SWI-Prolog


Compound Bodies

  • Body is a term – a comma term

    ?- (a, b, c, d) = (X, Y).

    X = a

    Y = b, c, d

  • Needs to be in parentheses when 2nd arg.

    ?- clause(sibs(_,_), (parent(_,_), _) ).

    Yes

Is there a clause of sibs/2 with a body like

parent(_,_),


Bodies of Facts

  • Puts true/0 in for body of fact

    parent(mark, alex).

    parent(bob, mark).

    parent(X, brian) :- parent(X, mark).

    ?- clause(parent(X, Y), Body).

    X = mark, Y = alex, Body = true ;

    X = bob, Y = mark, Body = true ;

    X = _1, Y = brian, Body = parent(_1,mark)


Looking at Built-in Code

  • Some built-in predicates are available

    ?- clause(member(X,Y), Body).

    X = _1, Y = [_1|_2], Body = true ;

    X = _1, Y = [_2|_3], Body = member(_1, _3)

  • Others are hidden

    ?- clause(clause(A,B), Body).

    ERROR: No permission to access private_procedure `clause/2'


Modifying Code

  • Replace every rule of the form

    • H :- …, different(X,Y), …

  • with

    • H :- …, X \= Y, …

  • (where the other bits don’t change)

  • Maybe for efficiency

    • H should be specified (else errors ensue)


Method for Modifying Code

  • Find a rule with matching head

    • Note: predicate must be dynamic

  • If it has a different(X,Y) in it,

    • replace it with X \= Y

    • retract old rule

    • assert new rule


Modification Predicate

modify_rule(Head, Old, New) :-

clause(Head, Body),

replace_code(Body, Old, New, NewBody),

retract(Head :- Body),

assert(Head :- NewBody).

replace_code((Old,More), Old, New, (New,More)).

replace_code((H,OldT), Old, New, (H,NewT)) :-

replace_code(OldT, Old, New, NewT).

replace_code(Old, Old, New, New).


Modifying Code

?- modify_rule(sib(_,_), different(X,Y), X\=Y).

before:

sib(A, B) :-

parent(A,C),

parent(B,C),

different(A,B).

  • Problem – only modifies one clause!

after:

sib(A, B) :-

parent(A,C),

parent(B,C),

A \= B.


Modifying All Clauses

  • Prolog prints bindings

    • ask for another solution

    • Prolog backs up to clause/2 & gets another rule

    • then changes that rule

  • Keep asking for answers until all done

    • it works – will stop when no rule has Old in it

    • it’s sort of like a loop


“Failure Driven Loops”

  • Need to make a change, then fail

    • Prolog will try another clause

  • Have predicate make a change, then fail

    • it will change all the rules before saying No

  • Says No even tho’ it worked!

    • if we put \+ in front, it’ll say Yes instead!

    • that’s more intuitive for user


Modify All

modify_all(Head, Old, New) :-

\+ modify_and_fail(Head, Old, New).

modify_and_fail(Head, Old, New) :-

modify_rule(Head, Old, New),

fail.

OR Just

modify_all(Head, Old, New) :-

\+ (modify_rule(Head, Old, New), fail).


Remaining Problem

  • too_different/3 is not fully changed

    • replace_code only changes first Old to New

    • backtracking doesn’t pick up new clause

  • Try to fix by making replace_code change all

    • unexpected side-effect: all X\=Y made the same

    • too_different(A,A,A) :- A\=A, A\=A, A\=A.

  • Too complicated for us!


Next Time

  • Definite Clause Grammars


  • Login