programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-recapitulare.pdf · tipuri de...

44
Programare logică An universitar 2013 2014 Anul III, Semestrul II Vasile Alaiba <[email protected]> http://profs.info.uaic.ro/~alaiba Facultatea de Informatică, Universitatea „Al.I.Cuza” Iaşi

Upload: others

Post on 29-Aug-2019

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Programare logică

An universitar 2013 – 2014

Anul III, Semestrul II

Vasile Alaiba <[email protected]>

http://profs.info.uaic.ro/~alaiba

Facultatea de Informatică, Universitatea „Al.I.Cuza” Iaşi

Page 2: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Sintaxa LP

Fie o mulţime de variabile propoziţionale, A

= {A1, A2, … }, mulţimea conectorilor logici

C = {, , } şi P = { ( , ) } mulţimea

parantezelor.

Formulele vor fi cuvinte peste alfabetul

L = A U C U P

Page 3: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Sintaxa LP

Baza (formulele elementare sunt formule). A LP .

Pas constructiv.

(i) Dacă F LP atunci ( F) LP.

(ii) Dacă F1, F2 LP atunci ( F1 F2 ) LP.

(iii) Dacă F1, F2 LP atunci ( F1 F2 ) LP.

(iv) Dacă F LP atunci (F) LP.

Page 4: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Arborele asociat unei formule

Să se construiască arborele asociat formulei:

A \/ B /\ ~C

~B /\ (C \/ B /\ A)

B -> A /\ ~B \/ A

Page 5: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Mulțimea subformulelor

Baza. F = A A. Atunci subf(F) = {A}.

Pas constructiv.

(i) F = ( F1). Atunci subf(F) = subf(F1) U { ( F1) }.

(ii) F = (F1 F2). Atunci subf(F) = subf(F1) U subf(F2)

U { (F1 F2) }.

(iii) F = (F1 F2). Atunci subf(F) = subf(F1) U

subf(F2) U { (F1 F2) }. (iv) F = (F1). Atunci subf(F) = subf(F1) U { (F1) }

Page 6: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Mulțimea subformulelor

Să se construiască mulțimea subformulelor

asociate formulei:

A \/ B /\ ~C

B -> A /\ ~B \/ A

Page 7: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Semantica LP Orice funcţie S, S : A B se numeşte asignare.

Pentru fiecare asignare S există o unică extensie a acesteia,

S’ : LP B (numită structură sau interpretare), care

satisface:

(i) S’(A) = S(A), pentru fiecare A A.

(ii) S’(( F)) = S’(F) , pentru fiecare F LP.

(iii) S’((F1 F2) ) = S’(F1) • S’(F2), pentru fiecare F1, F2 LP.

(iv) S’((F1 F2) ) = S’(F1) + S’(F2), pentru fiecare F1, F2 LP.

Page 8: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exercițiu

Fie F = A \/ B /\ ~C

Determinati o structură S astfel încât S(F) = 1

Determinati o structură S astfel încât S(F) = 0

Page 9: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Satisfiabilitate

O formulă F LP se numeşte satisfiabilă dacă

există măcar o structură S pentru care S(F) = 1

O formulă este validă (tautologie) dacă pentru

orice structură S, S(F) = 1

O formulă este nesatisfiabilă (contradicţie)

dacă pentru orice structură S, S(F) = 0

Page 10: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Forme normale în LP

Formă normală conjunctivă (FNC)

Clauze

Page 11: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Formă normală conjunctivă (FNC)

O formulă F LP se află în FNC dacă este o

conjuncţie de disjuncţii de literali, adică o conjuncţie

de clauze. Simbolic:

miLLF ji

n

jji

n

j

m

i

ii

,C notam ,)( ,1

i,11

Page 12: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Clauze (1)

Clauză

Este orice disjuncţie (finită) de literali.

Clauză Horn

Este o clauză care are cel mult un literal pozitiv.

Clauză pozitivă

Este o clauză care conţine doar literali pozitivi

Page 13: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Clauze (2)

Clauză negativă

Este o clauză care conţine doar literali negativi.

Clauză definită (definite clause)

Clauză Horn pozitivă

Conţine exact un literal pozitiv

Page 14: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Formule Horn

O formulă în FNC în care toate clauzele sunt

Horn

Scrierea implicațională

~A \/ ~B \/ C== A /\ B -> C

~A \/ ~B == A /\ B -> 0

A == 1 -> A

Page 15: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exercițiu

Să se aplice algoritmul Horn formulei:

F = ( A D ) ( C A D ) ( A

B ) D E

F = (D \/ A) /\ (A \/ B) /\ A /\ (B \/ C) /\ (C \/

D)

Page 16: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Rezoluție în LP

Fie clauzele C1, C2 , R.

R = ResL(C1, C2) (R este rezolventul lui C1,

C2), dacă există un literal L C1 astfel încât ~L

C2 şi R = (C1 \ {L}) U (C2 \ { ~L })

F este nesatisfiabilă dacă şi numai dacă

Res*(F).

Page 17: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exerciții

Găsiți o respingere pentru formula: F = {{A, B, C}, {A}, {A, B, C}, {A, B}}

Page 18: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Sintaxa LP1 (1)

variabile (funcţionale) X = {x1, x2, …}

simboluri predicative P = {P0, P1, …}

variabile predicative P0

simboluri funcţionale F = {F0, F1, ...}:

constante (funcţionale) F0

conectori logici C1 = {, , }

cuantificatori C2 = universali {(x) | x X} U

existenţiali {( x) | x X}

paranteze P = { (, ) }

Page 19: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Sintaxa LP1 (2)

Alf = X U (U Pi ) U (U Fi ) U C1 U C2 U P

T este mulţimea termilor (funcţionali)

Baza:

X T

Fo T

Pas constructiv:

Pentru fiecare n N*, f Fn, t1, t2, …, t n T,

avem f(t1, t2, …, t n) T.

Page 20: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Sintaxa LP1 (3)

LP1 este dată constructiv

Baza: At – mulţimea formulelor atomice

Po At

Pentru fiecare n N*, P Pn, t1, t2, …, tn T,

avem P(t1, t2, …, tn) At.

Pas constructiv: dacă F, F1, F2 LP1 atunci:

(F) LP1

(F1) (F2) LP1, (F1) (F2) LP1

(x)(F) LP1, ( x)(F) LP1

(F) LP1

Page 21: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exerciții

Identificați simbolurile care apar în formule.

Construiți mulțimea subformulelor și arborele

asociat.

Formulele:

(∀x)(P(x, a) ∧ Q(y) ∨ ¬(∃z)P(z, x))

(∃x)(∀z)(P(x, y, z) ∨ ¬Q(x)) ∧ (∀x)(Q(X) ∧

R(f(x, z), a))

Page 22: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Variabilă liberă şi legată

Fie F LP1, x X:

x – apariţie legată dacă este parte a unei

subformule G a lui F de forma

G1 = (x)(G)

G2 = (x)(G)

x – apariţie liberă în caz contrar.

Page 23: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Substituții

Substituție elementară este o pereche de tipul [x/t], unde x X, t T.

Prin substituţie vom înţelege o secvenţă finită de forma s = [x1/t1]•[x2/t2]• … •[xn/tn], nN, xiX, tiT.

O substituţie s se aplică unei formule F, rezultând o formulă G, notată (F)s, care se obţine din F prin înlocuirea fiecărei apariţii libere a variabilei xi cu termul ti, în ordinea dată în s.

Page 24: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Tipuri de substituții

Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine variabile libere care au apariţii legate în F.

O substituţie s este normalizată pentru F dacă (F)s = (F)s’, pentru fiecare s’ care este obţinută din s printr-o permutare a componentelor acesteia, deci ordinea de aplicare a substituţiilor elementare componente nu contează.

Substituţia vidă, notată [], este o secvență de 0 substituții elementare și nu face nicio transformare în formula F căreia îi este aplicată, deci (F)[] = F.

Page 25: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exerciții

Să se aplice substituția s = [x/f(z)][z/a][y/z]

formulelor:

F1 = (∀x)(P(x, a) ∧ Q(y) ∨ (∃z)P(z, x))

F2 = (∃x)(∀z)(P(x, y, z) ∨ Q(x)) ∧ (∀x)(Q(x) ∧

R(f(x, z), a))

F3 = P(x) ∨ P(y) ∧ (∀z)(∃x)Q(f(z), x)

F4 = (∀x)P(x, f(x)) ∧ Q(x) ∨ P(a, f(z))

F5 = (∃x)(∃y)(P(f(x, a), f(a, y)))

Page 26: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Structură: S = <US, IS>

US este o mulţime nevidă

IS : X U P U F

US U [US* B] U [US

* US]

Dacă x X, atunci IS (x) US

Dacă P P n, atunci IS (P) : B

Dacă F F n, atunci IS (F) : USn

US

Semantica LP1 (1)

Page 27: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Semantica LP1 (2)

Fie S = <US, IS>. Extensia sa este:

S’ : X U P U F U T U LP1

US U [US* B] U [US

* US] U B

Pentru fiecare a X U P U F :

S’(a) = S(a)

Pentru fiecare n N*, t1, t2, … , tn T , f Fn,

astfel încât t = f(t1, t2, …, tn)

S’(t) = S(f)(S’(t1), S’(t2), ... , S’(tn)) (US)

Page 28: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Semantica LP1 (3)

Baza. Fie A At .

A = P P0

S’ = S(P) B

A = P(t1, t2, …, tn), n N*, t1, t2 , ……, tn T

S’ (P) = S(P)(S’ (t1), S’ (t2), ... , S’ (tn)) B

Page 29: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Semantica LP1 (4)

Pas constructiv

F = ( F1 ). Atunci S’(F) = S’(F1)

F = (F1 F2). Atunci S’(F) = S’(F1) • S’(F2)

F = (F1 F2). Atunci S’ (F) = S’(F1) + S’(F2)

F = (x)(G). Atunci S’(F) = 1 ddacă pentru

fiecare u US avem S’[x/u](G) = 1

F = (x)(G). Atunci S’(F) = 1 ddacă există măcar

un u US astfel încât S’[x/u](G) = 1

Page 30: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exerciții

Pentru formula F determinați o structură S1 =

<US, IS> astfel încât S1(F) = 0 și o altă

structură S2 astfel încât S2(F) = 1.

F = P(x) ∨ P(y) ∧ (∀z)(∃x)Q(f(z), x)

Aplicați substituția s = [x/f(z)][z/b] formulei

F, apoi determinați o structură S astfel încât

S((F)s)=0

F = (∀x) (∃y)(P(x, a) ∧ Q(y) ∨ ¬(∃x)P(z, x))

Page 31: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Forme normale în LP1

Forma normală rectificată (FNR) O formulă F LP1 se numeşte rectificată dacă

nu conţine variabile care apar atât libere cât

şi legate şi

nu are cuantificatori care să lege aceeaşi

variabilă, dar pe poziţii diferite în formulă.

Page 32: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Forme normale în LP1

Forma normală prenex (FNP)

O formulă F LP1 este în formă normală

prenex dacă

F = (○1y1) …(○nyn)G, unde n N, ○i {, }, i

[n], iar

y1, … , yn sunt toate variabilele distincte care apar

(liber) în G.

În plus, G nu mai conţine cuantificatori.

Page 33: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Forme normale în LP1

Forma normală Skolem (FNS)

O formulă F LP1 este în formă normală

Skolem (FNS, pe scurt), dacă

are aspectul F = (x1) … (xk)G, unde G nu mai

conţine cuantificatori (este matricea lui F), iar

x1, x2, … , xk sunt variabile distincte şi reprezintă

exact variabilele care apar în G

Page 34: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Forme normale în LP1

Formă normală Skolem clauzală (FNSC)

O formulă F LP1 este în FNSC dacă

este în FNS şi

matricea sa este în FNC (forma normală

conjuctivă) într-un sens similar cu LP (literalii

reprezentând acum formule atomice din LP1 sau

negaţii ale lor).

Page 35: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exercițiu

Să se aducă la FNSC formula:

F = (∀x) (∃y)(P(x,z) ∧ Q(y) ∨ (∀z)(∃x)P(z, x))

F = (∀x)(P(x, y) ∧ (∃y)P(y, c))

Page 36: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Unificare

Fie L = {L1, L2, ... , Lk} o mulţime finită, nevidă, de literali

din LP1.

L este unificabilă dacă există o substituţie s astfel încât

card((L)s) = 1.

s se numeşte unificator pentru L.

O substituţie s se numeşte cel mai general unificator

(MGU) pentru o mulţime unificabilă L dacă pentru fiecare

unificator s’ există o substituţie sub astfel încât s’ = s • sub.

Page 37: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Rezoluție în LP1

Fie C1, C2 şi R clauze în LP1, C1 ≠ C2.

R se numeşte rezolvent pentru C1 şi C2 dacă:

(i) Există substituţiile s1 şi s2 astfel încât (C1)s1 şi (C2)s2 nu au

variabile comune.

(ii)Există L1, L2, ... , Lm (C1)s1 şi L’1, L’2, ... , L’n (C2)s2

astfel încât mulţimea: L = {L1, L2, ... , Lm, L’1, L’2, ... ,

L’n} este unificabilă.

(iii)Fie sub un cel mai general unificator pentru L.

R = (((C1)s1 \ {L1, L2, ... , Lm}) U ((C2)s2 \ {L’1, L’2, ... ,

L’n}))sub.

Page 38: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exercițiu

Demonstraţi utilizând rezoluţia că următoarea

formulă din LP1 este nesatisfiabilă:

F = (∀x)(∀y)(P(x,x)∧( P(x,g(y))∨Q(y))∧

Q(f(a)))

F = (x)(y)((P(x) P(f(c)) Q(y)) P(y)

(P(g(b, x)) Q(b)))

Page 39: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Temă curs

Un puzzle logic este un joc, textual sau vizual, bazat

pe deducţie.

Găsiţi un puzzle logic, scrieţi-l sub formă de

mulţime de clauze în LP1 şi căutaţi să îl rezolvaţi

folosind metoda rezoluţiei.

Veniţi cu tema la curs pentru a o prezenta.

Page 40: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exemplu: Problema lui „Einstein”

Sunt cinci case diferite, fiecare pictata in alta

culoare.

In fiecare casa locuieste o persoana de alta

nationalitate, care prefera propria sa bautura,

diferita de a celorlalti.

Fiecare om are pe langa el un animal distinct

si fumeaza o marca distincta de tigari.

Page 41: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exemplu: Problema lui „Einstein”

Se fac urmatoarele afirmatii:

1. Englezul locuieste in casa rosie.

2. Suedezul are un caine.

3. Danezul bea ceai.

4. Casa verde este la stanga casei pictata in

alb.

5. Persoana din casa verde bea cafea.

Page 42: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exemplu: Problema lui „Einstein”

6. Persoana care fumeaza Pall Mall creste

pasari.

7. Persoana din casa galbena fumeaza

Dunhill.

8. Persoana din casa din mijloc bea lapte.

9. Norvegianul locuieste in prima casa.

10. Persoana care fumeaza Blend locuieste in

casa vecina celei unde se cresc pisici.

Page 43: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exemplu: Problema lui „Einstein”

11. Persoana care creste cai locuieste langa cel care fumeaza Dunhill. 12. Persoana care fumeaza Blue Master bea bere. 13. Germanul fumeaza Prince. 14. Norvegianul locuieste alaturi de casa vopsita in albastru. 15. Cel care fumeaza Blend este vecin cu persoana care nu bea decat apa.

Page 44: Programare logică - profs.info.uaic.roalaiba/pub/prolog-2014/curs/2-Recapitulare.pdf · Tipuri de substituții Substituţia elementară [x/t] este permisă pentru F dacă t nu conţine

Exemplu: Problema lui „Einstein”

Intrebarea este:

Cine crește pești ?