Les porcs sont-ils capables de voler?

45

Tâche

Votre tâche consiste à écrire une fonction ou un programme dans une langue de votre choix qui analyse deux déclarations et détermine s’il est possible de conclure que, de ces déclarations, les porcs sont capables de voler.

Contribution

L'entrée est une chaîne pouvant être lue à partir de STDIN, prise comme argument de fonction ou même être stockée dans un fichier. L'entrée peut être décrite à l'aide du fichier EBNF suivant:

input = statement , {statement};
statement = (("Pigs are ", attribute) | ("Everything that is ", attribute, "is also ", attribute)), ". ";
attribute = [not], ("able to fly" | singleAttribute);
singleAttribute = letter, {letter};
letter = "a" | "b" | "c" | "d" | "e" | "f" | "g"
       | "h" | "i" | "j" | "k" | "l" | "m" | "n"
       | "o" | "p" | "q" | "r" | "s" | "t" | "u"
       | "v" | "w" | "x" | "y" | "z" ;

Exemple d'entrée (voir d'autres exemples ci-dessous):

Pigs are green. Everything that is green is also intelligent. Everything that is able to fly is also not intelligent. Pigs are sweet. 

Sortie

La sortie peut être renvoyée par votre fonction, être écrite dans un fichier ou imprimée dans STDOUT. Il y a 5 cas différents à traiter:

  1. Les déclarations données sont valides, cohérentes et ont pour conséquence logique que les porcs peuvent voler. Dans ce cas, vous devez sortir Yes.
  2. Les déclarations données sont valides, cohérentes et ont pour conséquence logique que les porcs ne peuvent pas voler. Dans ce cas, vous devez sortir No.
  3. Les affirmations données, valides et cohérentes ne permettent pas de conclure que les porcs peuvent voler ou non. Dans ce cas, vous devez sortir Maybe.
  4. Les déclarations données sont valides, mais pas cohérentes (c’est-à-dire qu’il ya une contradiction dans les déclarations données). Depuis ex falso quodlibet , nous décidons de sortir Yesdans ce cas.
  5. Les déclarations données ne sont pas valides, c’est-à-dire qu’elles ne sont pas formatées en fonction du fichier EBNF donné. Dans ce cas, vous pouvez faire ce que vous voulez.

Détails

  • Vous pouvez supposer que les attributs donnés sont indépendants les uns des autres. Ainsi, par exemple, un cochon peut être jeune et vieux, vert, rouge et bleu en même temps, sans causer d'incohérence. Cependant, un cochon peut ne pas être «vert» et «pas vert» en même temps, c'est une contradiction et doit être traité comme décrit dans (4).
  • Pour chaque attribut, supposons qu'il y ait au moins un objet (pas nécessairement un cochon) dans l'univers qui possède l'attribut donné et un objet qui ne l'a pas.

Exemple d'entrées et de sorties

Contribution:

Pigs are green. Everything that is green is also intelligent. Everything that is able to fly is also not intelligent. 

Production: Les porcs étant verts et donc intelligents, et tout ce qui est capable de voler n’est pas intelligent, les porcs ne peuvent pas voler. La sortie est No.

Contribution:

Pigs are old. Everything that is not able to fly is also not old. 

Production: Si les porcs n'étaient pas capables de voler, ils n'étaient pas non plus vieux. Mais comme ils sont vieux, vous devez sortir Yes.

Contribution:

Everything that is sweet is also not old. Everything that is intelligent is also blue. 

Sortie: Maybe .

Contribution:

Pigs are not able to fly. Everything that is red is also sweet. Everything that is sweet is also not red. 

Résultat: Bien que la première déclaration implique que les porcs ne peuvent pas voler, les déclarations suivantes se contredisent et par conséquent, le résultat doit être Yes.

Contribution:

Pigs are very smart. Pigs are able to fly. 

Sortie: Tout ce que vous voulez, car la chaîne ne correspond pas aux critères mentionnés ci-dessus.

Gagnant

C'est du , donc la réponse correcte la plus courte (en octets) est gagnante. Le gagnant sera choisi une semaine après la publication de la première réponse correcte.

Un cochon volant

vauge
la source
pourquoi le troisième exemple renvoie-t-il oui?
xem
10
J'envisage d'écrire une réponse qui traduise l'entrée en code Prolog.
Tal
1
Vous pouvez seulement conclure que rien de rouge n'existe. Les choses douces et non rouges vont bien.
user2357112 prend en charge Monica
1
J'espérais avoir plus d'exemples, juste pour pouvoir les faire moi-même.
cjfaure
1
@xem: ex falso quodlibet, cherchez sur wikipedia le principe de l'explosion. Si une contradiction existe, alors tout peut être prouvé. Donc, si «dieu existe» est vrai et «dieu n'existe pas» est vrai, tout peut être prouvé être vrai, donc les cochons peuvent voler peut être prouvé vrai.
fightermagethief

Réponses:

10

Perl, 363 353 350 347 343 297 266 264

$_=<>;s/able to fly/X/g;$m=' ?(not )?\b(P|\w+)';$h{$1?N.$2:$2}{$3?N.$4:$4}=$h{$3?$4:N.$4}{$1?$2:N.$2}=1while s/$m.{8}$m\.//;map{%x=0,r($_,$_)}%h;sub r{($a,$b)=@_;$e+=$h{$a}{N.$b};$x{$b}++or$h{$a}{$b}=1,map{r($a,$_)}%{$h{$b}}}print$e|$h{P}{X}?Yes:$h{P}{NX}?No:Maybe

Ungolfed / Explication:

# Read one line from STDIN
$_=<>;
# Replaces special attribute with X
s/able to fly/X/g;
# Prepare attribute match
$m=' ?(not )?\b(P|\w+)';
# Match "Everything that is A is also B. "
#                        "\bA........ \bB\."
# Match "Pigs are B. "
#     "\bP........\bB\."
while(s/$m.{8}$m\.//)
{
  # Add facts for A => B and !B => !A, where A may equal "P" for "Pigs are"
  # Facts are stored as a hash of hashes %h; keys%h are the source attributes;
  # keys%{$h{$a}} are the attributes that follow from attribute $a
  # A "not attribute" is stored as "Nattribute", while a "attribute" is just stored as "attribute"
  $h{$1?N.$2:$2}{$3?N.$4:$4}=$h{$3?$4:N.$4}{$1?$2:N.$2}=1
}
# For all known source attributes ... (this should really be keys%h but we dont mind the extra hashrefs)
map{%x=0,r($_,$_)}%h;
sub r
{
  ($a,$b)=@_;
  # ... remember that we hit a negation and therefor an inconsistency ...
  # If we check/add $b and find an existing "N$b" that means that attribute $b is supposed to be true and not true at the same time
  # It is cheaper bytewise to just add up all consistency errors (remember each fact has a hard value of 1) than to exit right here
  $e+=$h{$a}{N.$b};
  # ... remember that we processed this attribute for the current source attribute so we prevent loops ...
  $x{$b}++or
  # ... add a new fact and then follow the chains (again omitting keys).
  $h{$a}{$b}=1,map{r($a,$_)}%{$h{$b}}
}
# Did we happen on an inconsistency? Do pigs fly? Dont pigs fly? Maybe (Bitwise or is okay too)
print$e|$h{P}{X}?Yes:$h{P}{NX}?No:Maybe
Thaylon
la source
4
Ce serait génial si vous pouviez nous dire comment cela fonctionne / écrire des commentaires!
Flawr
Et un autre vote positif pour plus de commentaires ... quelque chose en particulier a besoin de plus d'explications?
Thaylon
Ajout de plus de commentaires ...
Thaylon
@AlanBerndt a suggéré un postfixe while. Depuis il ne peut pas commenter et je ne peux pas approuver. Je voudrais dire merci! ici.
Thaylon
10

Haskell, 586 566 547 octets

J'ai écrit ceci en partant du principe que pour chaque propriété P, il doit exister des x et y tels que P (x) est vrai et P (y) est faux; sans cette hypothèse, le quatrième exemple d'entrée n'aurait pas de contradiction et répondrait «Non».

#define X p s q m
#define W where
t=0<1;f=0>1;y="Yes"
l=length;r=filter;h=head;(#)=(,)
u 0=[[]];u n=[x:y|x<-[t,f],y<-u$n-1]
c l=all(==h l)l#and l
X[]|or[fst$c$map(!!(n-1))e|n<-[1..l$h e]]=y|z t=y|z f="No"|t="Maybe"W e=m$u$l s;z m=t#m==(c$map h$q e)
X("Pigs":_:y)=p v((r$(==a).(!!k)).q)m z W((k,v),z,a)=s%y
X(_:_:_:y)=p w q((r(\x->(x!!j/=a)||(x!!k==b))).m)v W((j,u),_:_:z,a)=s%y;((k,w),v,b)=u%z
s%("not":w)=(i,u,not p)W(i,u,p)=s%w
s%(_:"to":_:w)=(0#s,w,t)
s%(w:z)=(maybe(l s,s++[w#l s])(#s)$lookup w s,z,t)
main=interact$p[""#0]id id.words.r(/='.')

Cela devrait être compilé avec l'option de ligne de commande ghc "-cpp". L'entrée doit être terminée par EOF (^ D). Vous pouvez l'essayer en ligne sur http://melpon.org/wandbox/ , mais vous ne pouvez pas définir d'options de ligne de commande. Au lieu de cela, vous pouvez préfixer le programme avec l'option de langue

{-# LANGUAGE CPP #-}

Cela fonctionne en collectant le jeu de traits, puis en filtrant le jeu de valeurs -> évaluations de la vérité en utilisant les implications dans l'entrée. Le résultat est ensuite testé pour garantir que chaque trait peut être valablement attribué à la fois à Vrai et à Faux (l’échec est ici le cas ex falso quodlibet ). Enfin, il recherche les évaluations qui correspondent aux faits du cochon, en vérifiant la valeur "capable de voler" dans chaque évaluation.

Un certain nombre d'octets ont été perdus dans l'état de threading: l'ensemble des traits vus jusqu'à présent, la fonction sélecteur de faits porcs et la fonction de filtrage déterminée par les implications. La même idée serait probablement beaucoup plus courte dans un langage impur.

Edit: Sauvegardé de plusieurs octets par la suggestion de fier haskeller, puis un extra supplémentaire en remplaçant la liaison de z et "u% drop 2 z" par une liaison à "_: _: z" et "u% z", en économisant 3.

Edit 2: Enregistré un peu plus. Utilisation de l'astuce (#) = (,) pour enregistrer 2 octets et apprendre sur les synonymes de modèle ( https://ghc.haskell.org/trac/ghc/wiki/PatternSynonymes ), mais la notation était trop détaillée pour permettre de réaliser des économies éliminer le reste des paires dans ce programme. Réduisez encore les économies en modifiant les modèles recherchés par l'analyseur. Par exemple: si une phrase ne commence pas par Pigs et qu'il reste quelque chose dans l'état de l'analyseur, nous analysons une phrase "Tout ce qui est ..". Cela a sauvé beaucoup de caractères dans les modèles pour X et%.

Matt Noonan
la source
Votre hypothèse est correcte, j'ai oublié de le mentionner en premier lieu mais je l'ai maintenant ajoutée à la section détails!
vauge
2
Vous devriez inclure les drapeaux dans votre nombre d'octets (voir le wiki wiki pour code-golf ). C'est donc 607 octets.
nyuszika7h
Est-ce vraiment correct? Le lien ne mentionne que les indicateurs liés aux codages Unicode; meta mentionne un problème similaire concernant les drapeaux C ++ -D (un tricheur évident) vs -std = c ++ 11 (sélection d'une variation de langage spécifique, donc probablement ok). Les indicateurs IMO utilisés permettent d'activer une extension GHC assez commune de Haskell98, donc analogue à -std = c ++ 11. Ref: meta.codegolf.stackexchange.com/questions/1859/…
Matt Noonan
vous pouvez remplacer votre deuxième définition de u par u n=(:)<$>[t,f]<*>u(n-1)(bien que cela nécessite l'importation de Control.Applicative, donc, en deuxième lieu, c'est pire)
fier haskeller
1
vous pouvez remplacer la définition de c parc l=(all(==l!!0)l,and l)
fier haskeller
6

Python, 547 536 525 521 513 509 497 503 501

m=map
o='not ';R={'':{''}}
S=lambda x,y:filter(len,m(str.strip,x.split(y)))
N=lambda a:[o+a,a[4:]][a[:4]==o]
def C(s):a,c=S(s[19:],'is also');return[(a,c),(N(c),N(a))]
X=lambda A:A&set(m(N,A))and 1/0 or A
for a,c in sum(m(lambda x:[('',x[9:])]if'P'==x[0]else C(x),S(raw_input(),'.')),[]):R.setdefault(a,{a}).add(c)
def F(s):
 i,n={s},{s}
 while 1:
  for r in i:n|=R.get(r,n)
  if X(i)>=n:return i
  i|=n
try:a='able to fly';n=N(a);c={n:'No','':'Maybe'}[''.join({a,n}&m(F,R)[0])]
except:c='Yes'
print c

Pour chacune a -> bdes entrées, nous ajoutons la clause donnée et sa négation not b -> not a à l'ensemble de clauses, puis nous calculons l'ensemble des propositions pouvant être ->traitées à partir de toute proposition à l'aide d'une boucle à point fixe. Chaque fois que nous rencontrons une contradiction, nous jetons (et attrapons plus tard) un ZeroDivisionErroret imprimons Yes.

Enfin, nous vérifions si "capable de voler" (et / ou sa négation) est accessible à partir de la proposition "est un cochon" ''et imprimons la réponse appropriée.

EDIT : C'est buggy, le réparer. Fixé.

utilisateur2361830
la source
1
vous devriez pouvoir économiser 2 octets en plaçant le trybloc sur la même ligne quetry:
undergroundmonorail
@undergroundmonorail: merci d'avoir remarqué ça! changé cela.
user2361830
5

Ruby 1.9.3 ( 365 364 362)

h='able to fly'
i="(not )?(#{h}|\\w+)"
o=->s{n=Regexp.new(i+" (is also|are) "+i).match s
[[n[2],!n[1]],[n[5],!n[4]]]}
c=e=!z=[]
w=->r{z.member?(r)||(z<<(a,b=r)
c|=a[0]==b[0]&&a[1]!=b[1]
w[[[b[0],!b[1]],[a[0],!a[1]]]]
z.map{|q|q[1]==r[0]&&w[[q[0],r[1]]]})}
y=->x{z.member?([[p='Pigs',!e],[h,x]])}
f=->x{x.split(?.).map{|s|w[o[s]]}
c|y[!e]?'Yes':y[e]?'No':'Maybe'}

Usage

Le code ci - dessus définit une fonction fqui prend un paramètre représentatif de l'entrée de texte et les rendements Yes, Noou Maybe.

Par exemple:

f['Pigs are old. Everything that is not able to fly is also not old.']
=> "Yes"

Test en ligne: http://ideone.com/fxLemg

Le code non golfé (y compris les tests unitaires) est disponible ici .

Cristian Lupascu
la source
* sont disponibles (sous en-tête "test en ligne"). Les pluriels, mon bon ami.
Stan Strum
@StanStrum Merci! J'ai modifié le texte - je veux dire que le code est disponible et qu'il comprend également des tests unitaires.
Cristian Lupascu