webForumDet fria alternativet

någon som kan prolog?

9 svar · 433 visningar · startad av The_Hulk

The_HulkMedlem sedan juni 20031 837 inlägg
#1

skulle behöva lite hjälp.

Aleph_OneMedlem sedan juni 2003372 inlägg
#2

Kan en del, men det var ett tag sen så jag är grymt ringrostig på det.
Posta det du behöver hjälp med så kanske jag kan hjälpa dig. :)

The_HulkMedlem sedan juni 20031 837 inlägg
#3

gäller i och för sig en skoluppgift men jag får inte ordning på det.
man ska göra ett litet program som negerar ett satsuttryck.

ex: negera(icke p)
ska bli: p

negera(p och q)
ska bli: icke p eller icke q

har fått ordning på allt utom då man ska negera icke icke ...

hittar tyvärr inte uppgiftspappret nu, men hoppas du ändå kan förstå vad jag menar

% operator deklarerar de fyra konnektiven.
:- op(601, fy, icke).
:- op(602, xfx, och).
:- op(603, yfx, eller).
:- op(604, yfx, medför).

% Negerar satsuttrycket.
% ger negering. variablen Onegerat kan inte bestå av något konnektiv
% Ex. 'p' => 'icke p'
negera(Onegerat, icke Onegerat):-
    atom(Onegerat).

% negera ICKE
% tar bort negeringen icke från satsuttrycket.
% Ex. 'icke p' => 'p'
negera(icke Onegerat, Onegerat):-
    atom(Onegerat).
% ta bort 'icke' om det bara finns ett
negera(icke Onegerat, Onegerat):-
    \+ atom(Onegerat),
    \+ nextIcke(Onegerat).
% finns det två icke i rad så plocka bort dem och negera resten
negera(icke Onegerat, Negerat):-
    nextIcke(Onegerat),
    tabortIcke(Onegerat,Resten),
    negera(Resten, Negerat).

% negera OCH
% vanlig negering av OCH ger (icke Onegerat1 eller icke Onegerat2)
% Ex. 'p och q' => '(icke p eller icke q)'
negera(Onegerat1 och Onegerat2, Negerat1 eller Negerat2):-
     negera(Onegerat1, Negerat1),
     negera(Onegerat2, Negerat2).

% negera ELLER
% negering av ELLER ger (icke Onegerat1 och icke Onegerat2)
% Ex. 'p eller q' => '(icke p och icke q)'
% Fall 1
negera(Onegerat1 eller Onegerat2, (Negerat1 och Negerat2)):-
    negera(Onegerat1, Negerat1),
    negera(Onegerat2, Negerat2).

% negera MEDFÖR
% negering av MEDFÖR ger (Onegerat1 och icke Onegerat2)
% Ex. 'p medför q' => '(p och icke q)'
% Fall 1
negera(Onegerat1 medför Onegerat2, (Negerat1 och Negerat2)):-
    negera(icke Onegerat1, Negerat1),
    negera(Onegerat2, Negerat2).

nextIcke(icke _).

tabortIcke(icke Resten, Resten).
spangoMedlem sedan juni 20008 205 inlägg
#4

Missar jag nåt, eller gör du det inte extra krångligt nu?

negera(icke icke Vadsomhelst, Vadsomhelst).

på någon lämplig plats.

The_HulkMedlem sedan juni 20031 837 inlägg
#5

så kan man tyvärr inte göra, för det löser inte rekusivt

fick detta som svar från läraren.

Det räcker inte att ta bort icke på översta nivån.
Du måste gå på djupet i strukturerna:

?- negera(icke (p och icke(q eller r)),N).
N = p och icke (q eller r)

Svaret ska vara
N = p och (icke q och icke r)

Aleph_OneMedlem sedan juni 2003372 inlägg
#6

Var inne på nåt liknande det spango skrev.. annars vet jag tyvärr inte.

The_HulkMedlem sedan juni 20031 837 inlägg
#7

synd för jag kan inte heller komma på vad hur man ska fixa det.

spangoMedlem sedan juni 20008 205 inlägg
#8

Jag skrev ju förstås fel, menade:

negera(icke icke Vadsomhelst, NegVadsomhelst):-
        negera(Vadsomhelst, NegVadsomhelst).

redigerat »

Gaaah, jag har fått smygabstinens från Prolog :)
Hsh, predikatet ovan borde lösa din problem:

SICStus Prolog skrev:

?- negera(och(kiss, bajs), Blöja).

Blöja = eller(icke(kiss), icke(bajs))

Yes
?- negera(icke(icke(och(kiss, bajs))), Blöja).

Blöja = eller(icke(kiss), icke(bajs))

Yes

(ursäkta de infantila konstant/variabelnamnen :r )

Predikatet är det inte något fel på, om det inte går att använda beror det nog på din lärare ;)

Problemet du har just nu är väl att din lärare vill att endast atomer ska negeras när de körts genom negera, vilket inte är fallet nu (... väl?). Det är negera(icke Onegerad, Negerad) version 2 som är problemet.

Om du har negera(icke (p och icke(q eller r)), N) får du ju nu svaret N = (p och icke(q eller r)), vilket beror på att när du stöter på icke NågonIckeatom så tar du bara bort icke. De olika delarna av predikatet (eller vad de där ickeatomära sakerna nu heter...) skicka således bara tillbaka, utan icke:t. Det är ju inte det du vill göra. I mitt icke icke-predikat borde du kunna hitta en ledtråd, pilla lite innan du kommer tillbaka :)

The_HulkMedlem sedan juni 20031 837 inlägg
#9

Tack så jätte mycket för hjälpen!
hittade något i version 2 av negera icke som jag ändrade och nu verkar det fungera.

om ni är intresserade så ser negera icke ut så här nu:

% negera ICKE
% tar bort negeringen icke från satsuttrycket.
% Ex. 'icke p' => 'p'
negera(icke Onegerat, Onegerat):-
    atom(Onegerat).

% ta bort 'icke' om det bara finns ett
negera(icke Onegerat, Negerat2):-
    \+ atom(Onegerat),
    \+ nextIcke(Onegerat),
    negera(Onegerat, Negerat1),
    negera(Negerat1, Negerat2).
    
% finns det två icke i rad så plocka bort dem och negera resten
negera(icke icke Onegerat, Negerat):-
    negera(Onegerat, Negerat).

hoppas verkligen det är rätt nu.

spangoMedlem sedan juni 20008 205 inlägg
#10

Det borde det vara, det var nämligen ungefär det där jag kom fram till ;)

133 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
130 ms — hämta tråd, inlägg och bilagor (db)