270 likes | 375 Views
Kunstig intelligens (MNFIT-272) - høst 1999. Forelesning 7. Emner:. • . AI språk - Egenskaper generelt - Prolog - Lisp Usikkerhetsbehandling - Statistisk-orienterte metoder - Kunnskapsbaserte metoder. AI språk. •. Spesielt utviklet for å kunne behandle. symbolstrukturer. •.
E N D
Kunstig intelligens (MNFIT-272) - høst 1999. Forelesning 7 Emner: • AI språk - Egenskaper generelt - Prolog - Lisp Usikkerhetsbehandling - Statistisk-orienterte metoder - Kunnskapsbaserte metoder
AI språk • Spesielt utviklet for å kunne behandle symbolstrukturer. • Et AI språk er utviklet for ett bestemt beskrivelsesnivå. ◊ Kunnskapsnivå -språk støtter analyse og modellering på et konseptuelt - og intensjonelt - nivå. Ofte endel av et system eller en metodologi for kunnskapsakkvisisjon i generell forstand. Eksempler spenner fra grafiske editorer, der visualisering er sentralt, til formelle språk der sjekking av konsistens etc. er sentralt.
◊ Symbolnivå -språk støtter programmering og implementasjon. En kan skille mellom to typer språk: - Generelle programmeringsspråk (Lisp, Prolog, Smalltalk, C++, C, Pascal, Fortran, ...) - Spesielle høynivå-språk og KBS-skall (KEE, ART, Nexpert Object, CLIPS, KappaPC, ...)
1. Støtte til symbolbehandling • Symbolbehandling innebærer evne til å representere, generere, og operere på symbolske uttrykk og strukturer av slike. • Mønster-gjenkjenning (pattern matching) er sentralt - matching av beskrivelser og tilstander i søkerommet, hel eller delvis match. • Liste-behandling er sentralt - lister er egnet til lagring av symbolstrukturer, uansett kompleksitet
2. Fleksibilitet • Lett modifiserbare symbol-representasjoner • Data-drevet kontroll av eksekveringen • Bruker-spesifisert programkontroll
4. Sen binding av variable • Manipulering av variable uten å ha angitt verdi eller verdi-type. • Gradvis tilordning av typer og verdier til variable. • Verdier eller typer angis til å begynne med som beskrankninger (constraints), som så influerer på verdiene til relaterte variable, osv. (constraint propagation).
5. Veldefinert språk-semantikk • Enkel, klart forståelig språk-semantikk er en fordel. • Eksempler er 'Horn clause' logikk (Prolog), og rekursiv funksjonsteori (Lisp). • Pascal og Fortran, f.eks. har mer kompleks og uoversiktig semantikk. • Siden AI programmer ofte utfører en kompleks behandling, er det dessto viktigere at program- meringsspråket er enkelt bydg opp, og benyttes på en mest mulig klar og oversiktlig måte.
PROLOG • Basis: Matematisk logikk, 1. ordens predikatlogikk • Et Prolog program er et sett av fakta-uttrykk og implikasjoner: father(haakon,olav). male(olav). son(X,Y) :- father(Y,X), male(X). • En eksekvering av et Prolog program er en logisk deduksjon utifra et startbegrep (goal): son(olav,X).
• Deduksjon i et Prolog-program er basert på ' resolusjons' -algoritmen for teorembevis. • Det fins også andre deduktive bevis-algoritmer. Mange som arbeider med logikk-programmering utfra andre bevis-algortimer enn 'resolusjon', benytter Lisp som programmeringsspråk. • Prolog er et deklarativt språk Satt på spissen: "make declarations, not programs"
LISP • Basis: Matematisk teori for rekursive funksjoner, lambda-kalkyle. • Et Lisp program er et sett av funksjonsdefinisjoner og funksjonskall. En funksjonsdefinisjon består av et sett funksjonskall til andre definerte funksjoner, rekursivt: (push '(haakon olav) fathers) (push 'olav males) (defun is-father-of? (person-1 person-2) (equal person-2 (second (assoc person-1 fathers)))) (defun is-son-of? (person-1 person-2) (and (member person-1 males) (is-father-of? person-2 person-1))) (defun son-of (person) (second (assoc person fathers)))
• En eksekvering av et Lisp program er kall av en funksjon, hvis argumenter kan være kall til andre funksjoner, etc., rekursivt: (is-son-of? (son-of 'haakon) (father-of (son-of 'haakon))) • Lisp er et funksjonelt språk Satt på spissen: "make functions, not assignments"
LISP - basiselementer: s-expression list atom symbol number • En liste er en sekvens av atomer og/eller andre lister adskilt av blanke tegn og innesluttet i parentes. • Lister kan være nøstet i et uspesifisert antall nivåer
• Funksjonsdefinisjoner, dvs. programmer, såvel som datastrukturer er lister. - Programmer og data er av samme type, dvs. programmer kan tolkes som data og omvendt. • Datatyper tilordnes verdier , ikke variable • Den tomme listen, dvs. () eller NIL har en spesiell rolle. • Benytter dynamisk plass-allokering. "Garbarge collection" frigjør tidligere okkupert plass.
Side-effekter, Bindinger (funk-1 (funk-2 (funk-3 (funk-4 ...) ...) ...) ...) • En funksjon som utføres returnerer en verdi. Verdien gis tilbake til den kallende funksjonen, som igjen returnerer en verdi som gis tilbake til denne funksjonens kallende funksjon, osv. opp til topp-nivået i funksjonskall-kjeden. • Mange Lisp funksjoner har i tillegg side-effekter , dvs. at det skjer ting når en funksjon utføres som ikke fanges opp av retur-verdien. • Eksempler: (setq a 'b) ; returnerer: b ; side-effekt: symbolet a bindes til ; symbolet b
(defun a (n) (+ n 1)) ; returnerer symbolet a ; side-effekt: binder funksjons- ; definisjonen til a Funksjonene over benyttes kun pga. sine side-effekter. • (let ((a 'b) (c 2)) (list a c)) ; returnerer listen (b 2) ; side-effekt: ingen • let benyttes for å definere lokale variable inni en funksjon, og å gi dem initielle verdier setq benyttes for å definere globale variable, og for å endre verdien til variable innen en let blokk
Rekursjon og Lisp • Et rekursivt program er et program som kaller seg selv. En rekursiv funksjon er en funksjon som er definert ved seg selv. • Rekursive definisjoner er problemfrie såsant det fins et 'uthopp' fra rekursjonen, dvs. et test-kriterium som fører til at rekursjonsprosessen terminerer. • Lisp's listebehandlings-egenskaper gjør rekursjon til en relativt enkel og naturlig programmerings- mekanisme for symbolbehandling.
• Prinsippet for rekursiv listebehandling er: ◊ Funksjonen kalles med den aktuelle listen som ett av argumentene. ◊ Det sjekkes om terminerings-kriteriet er oppfylt. ◊ Funksjonen utføres ved å kombinere en operasjon på første element i argument-listen med et kall til funksjonen (seg selv) utført på de resterende elementer i listen.
Rekursjon Eksempel 1 For å utføre en operasjon på hvert element i en liste: 1. Hvis listen er tom, stopp. 2. Utfør operasjonen på første element i listen, og kall funksjonen med resten av listen som argument. ;;; Funksjon for å finne antall elementer i en liste (defun count-elements (liste) (cond ((null liste) 0) (t (+ 1 (count-elements (cdr liste)))))) Eksempel 2 For å utføre en operasjon på hvert element inntil en test slår til: 1. Hvis listen er tom, stopp og returner at test mislyktes. 2. Hvis testen slår til, stopp og returner aktuelt resultat, hvis ikke, kall funksjonen med resten av listen som argument. ;;; Funksjon for å sjekke om et gitt element er medlem av en liste: (defun my-member (element liste) (cond ((null liste) nil) ((equal element (car liste)) t) (t (my-member element (cdr liste)))))
Rekursjon • En funksjon kan kalle seg selv rekursivt flere steder i funksjonskroppen. Eksempel 3 ;;; Funksjon for å fjerne negative tall i en liste. Det rekursive ;;; kallet utføres både hvis testen slår til, og hvis den ikke gjør ;;; det: (defun filter-negatives (liste) (cond ((null liste) nil) ((plusp (car liste)) (cons (car liste) (filter-negatives (cdr liste)))) (t (filter-negatives (cdr liste))))) Numeriske funksjoner • Det er ikke bare for listebehandling at rekursive definisjoner er velegnet: ;;; Funksjon for å beregne fakultet av et tall, n! = 1*2*3*4*5*.....*(n-1)*n ;;; (defun fac (n) (cond ((= n 0) 1) (t (* n (fac (- n 1))))))
Iterasjon: • Rekursjon er ikke eneste metoden for å utføre repeterende programtrinn i Lisp. - Men ofte den enkleste - såsant en har trening i å tenke rekursivt! • Vanligste iterasjons -funksjoner: - do dolist dotimes - mapcar • (dolist (<var> <list> <result>) (<body>)) (defun count-elements (liste) (let ((len 0)) (dolist (element liste len) (setq len (+ len 1))))) • (do ((<var 1> <init 1> <update 1>) (<var 2> <init 2> <update 2>) ... (<var n> <init n> <update n>)) (<termination test> <returned result>) (<body>)) (defun count-elements (liste) (do ((len 0 (+ len 1)) (l liste (cdr l))) ((null l) len))) En enkel do-løkke - uten kropp (<body>) !!
Høyere ordens Lisp-funksjoner • Tar andre Lisp-funksjoner som argument Eksempel 1 ;;; Generell filter-funksjon [ikke standard Lisp funksjon] (defun filter (liste test-funksjon) (cond ((null liste) nil) ((funcall test-funksjon (car liste)) (cons (car liste) (filter (cdr liste) test-funksjon))) (t (filter (cdr liste) test-funksjon)))) Eksempel 2 mapcar Mapping-funksjonen • Iterativ funksjon for repeterende anvendelse av en funksjon på hvert element i en liste. > (mapcar #'count-atoms '((a b) (c (((d) e)) f ((g))) h)) (2 5 1) (defun square-root-elements (liste) (mapcar #'sqrt liste)) > (square-root-elements '(2 3 4 5 6)) (1.414213 1.732050 2 2.236067 2.449489)