Advertisement
Guest User

Untitled

a guest
May 20th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.04 KB | None | 0 0
  1. :- discontiguous exercitiul/2.
  2.  
  3. % Povestea (inspirată de Știrile de la Ora 5)
  4. %
  5. % În liniștitul nostru oraș s-a produs o crimă. Un individ a pătruns
  6. % în casa unui bătrân și l-a ucis. Cadavrul a fost ascuns de către
  7. % criminal și nu este de găsit. Este un caz complicat, dar doi
  8. % detectivi, D1 și D2, fac cercetări și au deja o listă de
  9. % suspecți. Știu despre fiecare dintre aceștia ce mașină are și care
  10. % este arma lui preferată.
  11. %
  12. % Pentru a rezolva cazul trebuie să afle cu ce armă a fost ucisă
  13. % victima și cu ce mașină a fugit criminalul. Din fericire, dacă se
  14. % poate vorbi despre așa ceva în cazul unei crime îngrozitoare, nu
  15. % există doi suspecți care să aibă aceeași mașină și aceeași armă.
  16. %
  17. % Cei doi detectivi se întâlnesc la secție. D1 s-a întâlnit cu un
  18. % martor și a aflat cu ce mașină a fugit criminalul. D2 a găsit arma
  19. % crimei. Cei doi se întâlnesc la secție, unde au următorul dialog pe
  20. % care tu îl asculți indiscret.
  21. %
  22. % D1: Știu că nu știi cine-i criminalul. Nici eu nu știu.
  23. % D2: Încă nu știu cine este.
  24. % D1: Nici eu nu știu încă cine este criminalul.
  25. % D1: Acum mi-am dat seama.
  26. % D2: Mi-am dat seama și eu.
  27. %
  28. % Cine este criminalul?
  29.  
  30. % ----------------------------------------------------------------------------
  31. % Mașini
  32.  
  33. conduce(aurel, ford).
  34. conduce(bogdan, bmw).
  35. conduce(cosmin, bmw).
  36. conduce(daniel, ford).
  37. conduce(eugen, bmw).
  38. conduce(florin, dacia).
  39. conduce(george, fiat).
  40. conduce(horia, audi).
  41. conduce(irina, dacia).
  42. conduce(jean, fiat).
  43. conduce(kiki, audi).
  44. conduce(laura, seat).
  45. conduce(marian, mercedes).
  46. conduce(nicodim, opel).
  47. conduce(ovidiu, honda).
  48. conduce(paul, honda).
  49.  
  50. % Arme
  51.  
  52. inarmat(aurel, sabie).
  53. inarmat(bogdan, pistol).
  54. inarmat(cosmin, arbaleta).
  55. inarmat(daniel, grenada).
  56. inarmat(eugen, grenada).
  57. inarmat(florin, sabie).
  58. inarmat(george, pistol).
  59. inarmat(horia, arbaleta).
  60. inarmat(irina, pusca).
  61. inarmat(jean, cutit).
  62. inarmat(kiki, prastie).
  63. inarmat(laura, pusca).
  64. inarmat(marian, cutit).
  65. inarmat(nicodim, prastie).
  66. inarmat(ovidiu, maceta).
  67. inarmat(paul, sabie).
  68.  
  69. % ----------------------------------------------------------------------------
  70. % 1. (1p) Scrieți un predicat suspect(Nume:Marca:Arma) care să fie
  71. % adevărat pentru fiecare suspect al problemei noastre.
  72. exercitiul(1, [1, puncte]).
  73.  
  74. suspect(Nume:Marca:Arma) :- conduce(Nume, Marca), inarmat(Nume, Arma).
  75.  
  76. check1:- tests([
  77. exp('setof(Nume_Marca_Arma, suspect(Nume_Marca_Arma), All)', [set('All', [aurel:ford:sabie, bogdan:bmw:pistol,
  78. cosmin:bmw:arbaleta, daniel:ford:grenada, eugen:bmw:grenada,
  79. florin:dacia:sabie, george:fiat:pistol, horia:audi:arbaleta,
  80. irina:dacia:pusca, jean:fiat:cutit, kiki:audi:prastie,
  81. laura:seat:pusca, marian:mercedes:cutit, nicodim:opel:prastie,
  82. ovidiu:honda:maceta, paul:honda:sabie])])
  83. ]).
  84.  
  85. % ----------------------------------------------------------------------------
  86. % 2. (1p) Scrieți un predicat au_pusca(-ListaNume) care să fie
  87. % adevărat atunci când ListaNume este lista cu numele tuturor celor care
  88. % au pușcă.
  89. exercitiul(2, [1, puncte]).
  90.  
  91. au_pusca(ListaNume) :- findall(Nume, inarmat(Nume, pusca), ListaNume).
  92.  
  93. check2:- tests([
  94. exp('au_pusca(ListaNume)', [set('ListaNume', [irina, laura])])
  95. ]).
  96.  
  97.  
  98. % ----------------------------------------------------------------------------
  99. % 3. (1p) Scrieți predicatele au_arma(+Arma, -ListaNume)
  100. % și au_marca(+Arma, -ListaNume), care să fie adevărate atunci când
  101. % ListaNume este lista cu numele tuturor celor care au arma de tipul
  102. % Arma, respectiv mașina de tipul Marca.
  103. exercitiul(3, [1, puncte]).
  104.  
  105. au_arma(Arma, ListaNume) :- findall(Nume, inarmat(Nume, Arma), ListaNume).
  106.  
  107. au_marca(Marca, ListaNume) :- findall(Nume, conduce(Nume, Marca), ListaNume).
  108.  
  109. check3:- tests([
  110. exp('au_arma(pistol, Pistolari)', [set('Pistolari', [bogdan, george])]),
  111. exp('au_arma(cutit, Cutitari)', [set('Cutitari', [jean, marian])]),
  112. exp('au_arma(maceta, Macelari)', [set('Macelari', [ovidiu])]),
  113. exp('au_marca(bmw, NuSemnalizeaza)', [set('NuSemnalizeaza', [bogdan, cosmin, eugen])]),
  114. exp('au_marca(dacia, ConducDacie)', [set('ConducDacie', [florin, irina])]),
  115. exp('au_marca(seat, ConducSeat)', [set('ConducSeat', [laura])]),
  116. exp('findall(_, au_marca(X,Y), L)', [cond(length(L, 9))])
  117. ]).
  118.  
  119. % ----------------------------------------------------------------------------
  120. % 4. (1.5p) Scrieți un predicat arme_bmw(ListaArme) care să fie adevărat
  121. % atunci când ListaArme reprezintă mulțimea tuturor armelor deținute
  122. % de conducători de bmw.
  123. exercitiul(4, [1.5, puncte]).
  124.  
  125. arme_bmw(ListaArme) :- au_marca(bmw, ListaNume),
  126. findall(Arma, (member(Nume, ListaNume), inarmat(Nume, Arma)), ListaArme).
  127.  
  128. check4:- tests([
  129. exp('arme_bmw(Arme)', [set('Arme', [arbaleta, grenada, pistol])])
  130. ]).
  131.  
  132.  
  133. % ----------------------------------------------------------------------------
  134. % 5. (1.5p) Scrieți un predicat arme_marca(Marca, ListaArme) care să
  135. % fie adevărat atunci când ListaArme reprezintă mulțimea tuturor
  136. % armelor deținute de conducători de mașini de tipul Marca.
  137. exercitiul(5, [1.5, puncte]).
  138.  
  139. arme_marca(Marca, ListaArme) :- bagof(Arma, Nume ^ (conduce(Nume, Marca), inarmat(Nume, Arma)), ListaArme).
  140.  
  141. check5:- tests([
  142. exp('arme_marca(bmw, ArmeBmw)', [set('ArmeBmw', [arbaleta, grenada, pistol])]),
  143. exp('arme_marca(dacia, ArmeDacia)', [set('ArmeDacia', [pusca, sabie])]),
  144. exp('arme_marca(seat, ArmeSeat)', [set('ArmeSeat', [pusca])]),
  145. exp('findall(Y, arme_marca(X,Y), [ _ , L | _ ])', [set('L', [arbaleta, grenada, pistol])])
  146. ]).
  147.  
  148. % ----------------------------------------------------------------------------
  149. % 6. (2p) Scrie un predicat marci_arma_unica(ListaMarci) care să afișeze
  150. % lista mașinilor pentru care lista armelor pe care le dețin
  151. % conducătorii unei mărci conține un singur element. Hint: folosiți-vă
  152. % de rezolvarea exercițiului 5. Nu folosiți length/2.
  153. exercitiul(6, [2, puncte]).
  154.  
  155. marci_arma_unica(ListaMarci) :- findall(Marca, (conduce(_, Marca), arme_marca(Marca, [_])), ListaMarci).
  156.  
  157. check6:- tests([
  158. exp('marci_arma_unica(ListaMarci)', [set('ListaMarci', [mercedes, opel, seat])])
  159. ]).
  160.  
  161. % ----------------------------------------------------------------------------
  162. % ----------------------------------------------------------------------------
  163.  
  164. % Să revenim la secție de poliție unde tu tragi cu urechea la dialogul
  165. % dintre cei doi detectivi:
  166. %
  167. % Prima replică:
  168. % Detectiv A : Știam că nu știi cine-i criminalul.
  169. %
  170. % Ce înseamnă asta? Detectivul A știe mașina cu care a fugit
  171. % suspectul. Această marcă de mașină este condusă de suspecți care
  172. % mânuiesc diferite arme. Dacă măcar una dintre aceste arme ar fi
  173. % aparținut doar unui singur suspect, atunci Detectivul B ar fi putut
  174. % ști care este soluția acestui caz.
  175. %
  176. % Ce soluții eliminăm?
  177. %
  178. % Dacă Detectivul A ar fi aflat că adevăratul criminal a condus o
  179. % Honda, atunci ar fi existat două soluții posibile:
  180. %
  181. % ovidiu - honda - maceta
  182. % paul - honda - sabie
  183. %
  184. % Dar cum nu există decât un singur individ care are macetă (Ovidiu),
  185. % Detectivul A nu ar fi putut afirma că Detectivul B nu poate ști.
  186. %
  187. % honda nu este, deci, o soluție
  188. %
  189. % Trebuie eliminate toate mașinile care sunt "în pereche" cu arme
  190. % pentru care nu există mai multe posibilități.
  191.  
  192. % ----------------------------------------------------------------------------
  193. % 7. (2.5p) Scrie un predicat suspect1/1 care este adevărat doar pentru
  194. % numele suspecților care respectă condiția impusă de replica
  195. % Detectivului A: niciuna dintre armele asociate cu mașina suspectului
  196. % nu indică în mod unic un anumit individ.
  197. exercitiul(7, [2.5, puncte]).
  198.  
  199. suspect1(Nume:Marca:Arma) :- suspect(Nume:Marca:Arma), arme_marca(Marca, ListaArme),
  200. forall(member(A, ListaArme), au_arma(A, [_, _ | _])).
  201.  
  202. check7:- tests([
  203. exp('setof(Nume_Marca_Arma, suspect1(Nume_Marca_Arma), All)',
  204. [set('All',
  205. [aurel:ford:sabie,bogdan:bmw:pistol,cosmin:bmw:arbaleta,
  206. daniel:ford:grenada,eugen:bmw:grenada,florin:dacia:sabie,
  207. george:fiat:pistol,horia:audi:arbaleta,irina:dacia:pusca,
  208. jean:fiat:cutit,kiki:audi:prastie,laura:seat:pusca,
  209. marian:mercedes:cutit,nicodim:opel:prastie])])
  210. ]).
  211.  
  212. % ----------------------------------------------------------------------------
  213. % A doua replică:
  214. %
  215. % Detectivul A: Nici eu nu știu!
  216. %
  217. % 8. (1.5p) Scrie un predicat suspect2/1 care este adevărat doar pentru
  218. % numele suspecților care respectă condiția impusă de replica
  219. % Detectivului A: marca nu indică unic un individ.
  220. %
  221. % Atenție: informația ce trebuie filtrată acum este cea care
  222. % corespunde primei replici.
  223. exercitiul(8, [1.5, puncte]).
  224.  
  225. suspect2(Nume:Marca:Arma) :- suspect1(Nume:Marca:Arma),
  226. findall(Name, suspect1(Name:Marca:_), [_, _ | _]).
  227.  
  228. check8:- tests([
  229. exp('setof(Nume_Marca_Arma, suspect2(Nume_Marca_Arma), All)',
  230. [set('All',
  231. [aurel:ford:sabie,bogdan:bmw:pistol,cosmin:bmw:arbaleta,
  232. daniel:ford:grenada,eugen:bmw:grenada,florin:dacia:sabie,
  233. george:fiat:pistol,horia:audi:arbaleta,irina:dacia:pusca,
  234. jean:fiat:cutit,kiki:audi:prastie])])
  235. ]).
  236.  
  237. % ----------------------------------------------------------------------------
  238. % A treia replică:
  239. %
  240. % Detectivul B: Nici eu nu știu!
  241. %
  242. % 9. (1p) Scrie un predicat suspect3/1 care este adevărat doar pentru
  243. % numele suspecților care respectă condiția impusă de replica
  244. % Detectivului B: arma nu identifică unic un individ.
  245. %
  246. % Atenție: informația ce trebuie filtrată acum este cea care
  247. % corespunde primelor două replici.
  248. exercitiul(9, [1, puncte]).
  249.  
  250. suspect3(Nume:Marca:Arma) :- suspect2(Nume:Marca:Arma),
  251. findall(Name, suspect2(Name:_:Arma), [_, _ | _]).
  252.  
  253. check9:- tests([
  254. exp('setof(Nume_Marca_Arma, suspect3(Nume_Marca_Arma), All)',
  255. [set('All',
  256. [aurel:ford:sabie,bogdan:bmw:pistol,cosmin:bmw:arbaleta,
  257. daniel:ford:grenada,eugen:bmw:grenada,florin:dacia:sabie,
  258. george:fiat:pistol,horia:audi:arbaleta])])
  259. ]).
  260.  
  261. % ----------------------------------------------------------------------------
  262. % A patra replică:
  263. %
  264. % Detectivul A: Eu tot nu știu!
  265. %
  266. % 10. (1p) Scrie un predicat suspect4/1 care este adevărat doar pentru
  267. % numele suspecților care respectă condiția impusă de replica
  268. % Detectivului A.
  269. %
  270. % Atenție: informația ce trebuie filtrată acum este cea care
  271. % corespunde primelor trei replici.
  272. exercitiul(10, [1, puncte]).
  273.  
  274. suspect4(Nume:Marca:Arma) :- suspect3(Nume:Marca:Arma),
  275. findall(Name, suspect3(Name:Marca:_), [_, _ | _]).
  276.  
  277. check10:- tests([
  278. exp('setof(Nume_Marca_Arma, suspect4(Nume_Marca_Arma), All)',
  279. [set('All',
  280. [aurel:ford:sabie,bogdan:bmw:pistol,cosmin:bmw:arbaleta,
  281. daniel:ford:grenada,eugen:bmw:grenada])])
  282. ]).
  283.  
  284. % ----------------------------------------------------------------------------
  285. % A cincea replică:
  286. %
  287. % Detectivul B: Eu am aflat!
  288. %
  289. % 11. (0.5p) Scrie un predicat suspect5/1 care este adevărat doar pentru
  290. % numele suspecților care respectă condiția impusă de replica
  291. % Detectivului B.
  292. %
  293. % Atenție: informația ce trebuie filtrată acum este cea care
  294. % corespunde primelor patru replici.
  295. exercitiul(11, [0.5, puncte]).
  296.  
  297. suspect5(Nume:Marca:Arma) :- suspect4(Nume:Marca:Arma),
  298. findall(Name, suspect4(Name:_:Arma), [_]).
  299.  
  300. check11:- tests([
  301. exp('setof(Nume_Marca_Arma, suspect5(Nume_Marca_Arma), All)',
  302. [set('All',
  303. [aurel:ford:sabie,bogdan:bmw:pistol,cosmin:bmw:arbaleta])])
  304. ]).
  305.  
  306. % ----------------------------------------------------------------------------
  307. % A șasea replică:
  308. %
  309. % Detectivul A: Și eu am aflat!
  310. %
  311. % 12. (0.5p) Scrie un predicat suspect6/1 care este adevărat doar pentru
  312. % numele suspecților care respectă condiția impusă de replica
  313. % Detectivului A.
  314. %
  315. % Atenție: informația ce trebuie filtrată acum este cea care
  316. % corespunde primelor cinci replici.
  317. exercitiul(12, [0.5, puncte]).
  318.  
  319. suspect6(Nume:Marca:Arma) :- suspect5(Nume:Marca:Arma),
  320. findall(Name, suspect5(Name:Marca:_), [_]).
  321.  
  322. check12:- tests([
  323. exp('setof(Nume_Marca_Arma, suspect6(Nume_Marca_Arma), All)',
  324. [set('All',
  325. [aurel:ford:sabie])])
  326. ]).
  327. %% ----------------------------------------
  328. %% ----------------------------------------
  329.  
  330. testtimelimit(5). % în secunde
  331.  
  332. test_mode(quickcheck) :- \+ test_mode(vmchecker).
  333.  
  334. :-dynamic(punct/2).
  335. :-dynamic(current/1).
  336. %:-clean.
  337.  
  338. clean :- retractall(punct(_, _)), retractall(current(_)).
  339.  
  340. testtest(5).
  341. testtest(6).
  342. testtest(9).
  343. testtest(a, 5).
  344. testtest(b, _).
  345. testtest(d, [2, 1, 3]).
  346. testtest(e, [2, 1, 3, 1, 2]).
  347. testtest(1, 2, 3).
  348. testtest(c, X, X).
  349. testtest(d, 5, excepting) :- X is 5 / 0, write(X).
  350. testtest(d, 5, limitless) :- testtest(d, 5, limitless).
  351.  
  352. testtest :- tests([
  353. % chk(P) ("check") verifică evaluarea cu succes a lui P
  354. chk(testtest(5)), % a
  355. chk(testtest(6)), % b % eșuează
  356. % uck(P) ("uncheck") verifică evaluarea cu eșec a lui P
  357. uck(testtest(6)), % c
  358. uck(testtest(5)), % d % eșuează
  359. % exp(P, Exps) ("expect") verifică evaluarea cu succes a lui P și a unor condiții
  360. % P este dat ca șir de caractere pentru o verificare și afișare mai bune.
  361. % Condițiile sunt evaluate pe rând și independent unele de altele.
  362. % Dacă în lista de condiții avem un nume de variabilă,
  363. % se verifică că aceasta a fost legat la valoarea care urmează imediat în listă.
  364. % valoarea de verificat nu poate conține variabile din interogare
  365. % (pentru asta folosiți cond, vezi mai jos).
  366. exp('testtest(X, X)', ['X', b]), % e
  367. exp('testtest(X, Y, Z)', ['X', 1, 'Y', 2, 'Z', 3]), % f
  368. exp('testtest(X, X)', ['X', a]), % g % eșuează
  369. % Dacă în lista de condiții avem v('Var'), se verifică că Var a rămas nelegată.
  370. exp('testtest(b, Y)', [v('Y')]), % h
  371. exp('testtest(a, Y)', [v('Y')]), % i % eșuează
  372. % Dacă în lista de condiții avem cond('P'), se verifică că P este adevărat.
  373. % Diversele condiții din structuri cond diferite se verifică independent.
  374. exp('testtest(c, X, X)', [v('X'), cond('X==X')]), % j
  375. % Dacă în lista de condiții avem set('V', Set), se verifică că V este legată la mulțimea Set.
  376. % Duplicatele contează.
  377. exp('testtest(d, L)', [set('L', [1, 2, 3]), 'L', [1, 2, 3]]), % k % eșuează pe a 2a condiție
  378. exp('testtest(d, L)', [set('L', [2, 3, 4, 5])]), % l
  379. exp('testtest(e, L)', [set('L', [1, 2, 3])]), % m
  380. % setU funcționează la fel, dar ignoră duplicatele.
  381. exp('testtest(e, L)', [setU('L', [1, 2, 3])]), % n
  382. % ckA(P, Argss) ("check all") verifică evaluarea cu succes a lui P pe fiecare dintre variantele de argumente din Argss.
  383. % e.g. dacă P este pred, iar Argss este [(1, a, []), (2, b, [5])],
  384. % se vor evalua atomii pred(1, a, []) și pred(2, b, [5]).
  385. ckA('testtest', [(a, 5), (b, 1), (b, 3), (b, 4)]), %o
  386. ckA('testtest', [(a, 5), (c, 1), (c, 3), (b, 4)]), %p
  387. % ech(P, Conds) ("each") verifică dacă condițiile țin pentru fiecare dintre soluțiile lui P
  388. ech('testtest(X)', ['X < 10', 'X > 3']), % q
  389. ech('testtest(X)', ['X > 3', 'X > 5']), % r
  390. % nsl(P, Template, NSols) ("N Solutions") verifică dacă lungimea lui L din findall(P, Template, L) este NSols
  391. 2, nsl('testtest(X, Y)', '(X, Y)', 4), % s
  392. % testul de mai sus valorează de 2 ori mai mult decât celelalte
  393.  
  394. % sls(P, Template, Sols) ("Solutions") verifică dacă findall(P, Template, L) leagă L la aceeași mulțime cu Sols.
  395. % Duplicatele contează
  396. 2, sls('testtest(X, X)', '(X, X)', [(b, b)]), % t
  397. % testul de mai sus valorează de 2 ori mai mult decât celelalte
  398.  
  399. sls('testtest(X, Y)', '(X, Y)', [(b, 5)]), % u
  400. % gestionare exceptii
  401. chk(testtest(d, 5, excepting)),
  402. % gestionare limita de timp
  403. chk(testtest(d, 5, limitless))
  404. ]).
  405.  
  406. % aceasta va fi ordinea de testare
  407. vmpoints(1, 5).
  408. vmpoints(T, 2.5) :- member(T, ['2a', '2b']).
  409.  
  410. % entry point (for users) for vm tests.
  411. vmtest(T) :-
  412. vmtest(T, Score),
  413. format('Total: ~w.', [Score]).
  414.  
  415. % performes a vm test, outputs score.
  416. vmtest(T, Score) :-
  417. once(vmpoints(T, Pts)),
  418. tt(T, TestList),
  419. tests(TestList, Pts, T, Score).
  420.  
  421. tt(1, [
  422. chk(testtest(5)),
  423. chk(testtest(6)),
  424. uck(testtest(6)),
  425. uck(testtest(5))
  426. ]).
  427. tt('2a', [
  428. exp('testtest(X, X)', ['X', b])
  429. ]).
  430. tt('2b', [
  431. exp('testtest(X, Y, Z)', ['X', 1, 'Y', 2, 'Z', 3]),
  432. exp('testtest(X, X)', ['X', a])
  433. ]).
  434.  
  435.  
  436. % entry point for quick check; handles checking all exercises or just
  437. % one.
  438. tests(Tests) :- ( current(_), ! ; retractall(punct(_, _))),
  439. ( current(Ex), !, exercitiul(Ex, [Pts | _]), Total is Pts
  440. ; Total is 100, Ex = none
  441. ),
  442. tests(Tests, Total, Ex, Score),
  443. ( current(Ex), assert(punct(Ex, Score)), !
  444. ; format('Rezolvat ~0f%.~n', [Score])
  445. ), !.
  446.  
  447. tests(_) :- failure(unknown, 'INTERN: tests/1 failed').
  448.  
  449. tests(Tests, TotalPoints, Ex, Score) :-
  450. total_units(Tests, TF),
  451. Unit is TotalPoints / TF,
  452. tests(Tests, Ex, 1, Unit, 0, Score), !.
  453. tests(_, _, Ex, _) :- failure(Ex, 'INTERN: tests/4 failed').
  454.  
  455. % iterates through tests, handles test index, generates test id, adds
  456. % points
  457. tests([], _, _, _, Points, Points) :- !.
  458. tests([Fraction, T|R], Ex, Idx, Unit, PointsIn, PointsOut) :-
  459. number(Fraction), !, test(T, Ex, Idx, Fraction, Unit, PointsIn, PointsOut1),
  460. tests(R, Ex, Idx+1, Unit, PointsOut1, PointsOut).
  461. tests([T|R], Ex, Idx, Unit, PointsIn, PointsOut) :-
  462. test(T, Ex, Idx, 1, Unit, PointsIn, PointsOut1),
  463. tests(R, Ex, Idx+1, Unit, PointsOut1, PointsOut).
  464. tests(_, Ex, _, _, _, _) :- failure(Ex, 'INTERN: tests/6 failed').
  465.  
  466. total_units([], 0).
  467. total_units([P, _|R], Tot) :- number(P), !, total_units(R, TotR), Tot is TotR + P.
  468. total_units([_|R], Tot) :- total_units(R, TotR), Tot is TotR + 1.
  469.  
  470. test(T, NEx, Idx, Fraction, Unit, PointsIn, PointsOut) :-
  471. IdxI is Idx + 96, char_code(CEx, IdxI),
  472. ( NEx == none, !, swritef(Ex, '%w|', [CEx]) ; swritef(Ex, '[%w|%w]', [NEx, CEx])),
  473. testtimelimit(Time), swritef(MTime, 'limita de %w secunde depasita', [Time]),
  474. ( catch(
  475. catch(call_with_time_limit(Time, once(test(Ex, T))),
  476. time_limit_exceeded,
  477. except(Ex, MTime)
  478. ),
  479. Expt,
  480. ( swritef(M, 'exceptie: %w', [Expt]),
  481. except(Ex, M))
  482. ),
  483. !, success(Ex, Fraction, Unit, Points),
  484. PointsOut is PointsIn + Points
  485. ; PointsOut = PointsIn).
  486. test(_, Ex, Idx, _, _, _, _) :- failure(Ex/Idx, 'INTERN: test/7 failed').
  487.  
  488. success(Ex, Fraction, Unit, Score) :-
  489. Score is Fraction * Unit,
  490. ( test_mode(vmchecker), !,
  491. format('+~2f ~10t ~w Corect.~n', [Score, Ex])
  492. ; format('~w[OK] Corect. +~2f.~n', [Ex, Score])).
  493. failure(Ex, M) :-
  494. ( test_mode(vmchecker), !,
  495. format('+0.0 ~10t ~w ~w~n', [Ex, M]), fail
  496. ; format('~w[--] ~w~n', [Ex, M]), fail).
  497. except(Ex, M) :-
  498. ( test_mode(vmchecker), !,
  499. format('+0.0 ~10t ~w Exception: ~w~n', [Ex, M]), fail
  500. ; format('~w[/-] ~w~n', [Ex, M]), fail).
  501.  
  502. test(Ex, chk(P)) :- !, testCall(Ex, P).
  503. test(Ex, uck(P)) :- !, testCall(Ex, \+ P).
  504. test(Ex, exp(Text, ExpList)) :- !,
  505. read_term_from_atom(Text, P, [variable_names(Vars)]),
  506. testCall(Ex, P, Text), testExp(Ex, Text, Vars, ExpList).
  507. test(_, ckA(_, [])) :- !.
  508. test(Ex, ckA(Pred, [Test|Tests])) :- !,
  509. swritef(S, '%w(%w)', [Pred, Test]),
  510. read_term_from_atom(S, P, []),
  511. testCall(Ex, P, S), test(Ex, ckA(Pred, Tests)).
  512. test(_, ech(_, [])) :- !.
  513. test(Ex, ech(Text, [Cond|Conds])) :- !,
  514. swritef(S, '%w|%w', [Text, Cond]),
  515. read_term_from_atom(S, P|Q, [variable_names(Vars)]),
  516. forall(P, (
  517. swritef(Msg, '%w pentru soluția %w a predicatului %w', [Cond, Vars, Text]),
  518. testCall(Ex, Q, Msg))),
  519. test(Ex, ech(Text, Conds)).
  520. test(Ex, nsl(Text, Tmplt, N)) :- !,
  521. swritef(S, 'findall(%w, %w, TheList)', [Tmplt, Text]),
  522. read_term_from_atom(S, P, [variable_names(Vars)]),
  523. testCall(Ex, P, S), testNSols(Ex, Text, Vars, N).
  524. test(Ex, sls(Text, Tmplt, Sols)) :- !,
  525. swritef(S, 'findall(%w, %w, TheList)', [Tmplt, Text]),
  526. read_term_from_atom(S, P, [variable_names(Vars)]),
  527. testCall(Ex, P, S), testSols(Ex, Text, Vars, Sols).
  528. test(Ex, sSO(Text, Tmplt, Sols)) :- !,
  529. swritef(S, 'setof(%w, %w, TheList)', [Tmplt, Text]),
  530. read_term_from_atom(S, P, [variable_names(Vars)]),
  531. testCall(Ex, P, S), testSols(Ex, Text, Vars, Sols).
  532. test(Ex, _) :- failure(Ex, 'INTERN: Test necunoscut').
  533.  
  534. % Pentru exercițiul Ex, evaluează clauza Do, dată ca termen.
  535. % Opțional, în mesajul de eroare interogarea poate fi afișată ca
  536. % parametrul Text.
  537. testCall(Ex, Do) :- swritef(Text, '%q', [Do]), testCall(Ex, Do, Text).
  538. testCall(Ex, Do, Text) :-
  539. catch((call(Do), !
  540. ; !, swritef(M, 'Interogarea %w a esuat.', [Text]), failure(Ex, M)
  541. ), Exc,
  542. (swritef(M, 'Interogarea %w a produs exceptie: %w', [Text, Exc]),
  543. except(Ex, M))
  544. ).
  545.  
  546. testExp(_, _, _, []) :- !.
  547. testExp(Ex, Text, Vars, [v(Var) | Rest]) :- !,
  548. ( getVal(Var, Vars, V), !,
  549. ( var(V), !, testExp(Ex, Text, Vars, Rest) ;
  550. swritef(M, 'Interogarea %w leaga %w (la valoarea %w) dar nu ar fi trebuit legata.',
  551. [Text, Var, V]), failure(Ex, M)
  552. )
  553. ;
  554. swritef(M, 'INTERN: Interogarea %w nu contine variabila %w.', [Text, Var]),
  555. failure(Ex, M)
  556. ).
  557. testExp(Ex, Text, Vars, [set(Var, Set) | Rest]) :- !,
  558. ( getVal(Var, Vars, V), !,
  559. testSet(Ex, Text, 'intoarce', V, Set),
  560. testExp(Ex, Text, Vars, Rest)
  561. ;
  562. swritef(M, 'INTERN: Interogarea %w nu contine variabila %w.', [Text, Var]),
  563. failure(Ex, M)
  564. ).
  565. testExp(Ex, Text, Vars, [setU(Var, Set) | Rest]) :- !,
  566. ( getVal(Var, Vars, V), !,
  567. testSetU(Ex, Text, 'intoarce', V, Set),
  568. testExp(Ex, Text, Vars, Rest)
  569. ;
  570. swritef(M, 'INTERN: Interogarea %w nu contine variabila %w.', [Text, Var]),
  571. failure(Ex, M)
  572. ).
  573. testExp(Ex, Text, Vars, [cond(Cond) | Rest]) :- !,
  574. swritef(S, "(%w, %w)", [Text, Cond]),
  575. read_term_from_atom(S, P, []),
  576. (
  577. call(P), !, testExp(Ex, Text, Vars, Rest)
  578. ;
  579. swritef(M, 'Dupa interogarea %w conditia %w nu este adevarata.', [Text, Cond]),
  580. failure(Ex, M)
  581. ).
  582. testExp(Ex, Text, Vars, [Var, Val | Rest]) :- !,
  583. ( getVal(Var, Vars, V), !,
  584. ( V == Val, !, testExp(Ex, Text, Vars, Rest) ;
  585. swritef(M, 'Interogarea %w leaga %w la %w in loc de %w.',
  586. [Text, Var, V, Val]), failure(Ex, M)
  587. )
  588. ;
  589. swritef(M, 'INTERN: Interogarea %w nu contine variabila %w.', [Text, Var]),
  590. failure(Ex, M)
  591. ).
  592. testExp(Ex, _, _, [X | _]) :- !,
  593. swritef(M, 'INTERN: element necunoscut pentru exp: %w', [X]),
  594. failure(Ex, M).
  595. testExp(Ex, _, _, X) :- !,
  596. swritef(M, 'INTERN: format gresit pentru exp: %w', [X]),
  597. failure(Ex, M).
  598.  
  599. testNSols(Ex, Text, Vars, N) :-
  600. ( getVal('TheList', Vars, V), length(V, NSols), !,
  601. ( NSols =:= N, !
  602. ; swritef(M, 'Numarul de solutii pentru %w este %w in loc de %w.',
  603. [Text, NSols, N]), failure(Ex, M)
  604. )
  605. ; failure(Ex, 'INTERNAL: nu avem variabila TheList sau aceasta nu este lista.')
  606. ).
  607.  
  608. testSols(Ex, Text, Vars, Sols) :-
  609. ( getVal('TheList', Vars, V), !,
  610. testSet(Ex, Text, 'are ca solutii', V, Sols)
  611. ; failure(Ex, 'INTERNAL: nu avem variabila TheList sau aceasta nu este lista.')
  612. ).
  613.  
  614. testSetU(Ex, Text, TypeText, SetG, SetE) :- sort(SetG, SetGUnique),
  615. testSet(Ex, Text, TypeText, SetGUnique, SetE).
  616. testSet(Ex, Text, TypeText, SetG, SetE) :- msort(SetG, SetGSorted),
  617. ( SetGSorted == SetE, ! ;
  618. testSetMinus(SetG, SetE, TooMuch),
  619. testSetMinus(SetE, SetG, TooLittle),
  620. ( TooMuch == [], TooLittle == [], !,
  621. M1 = 'vezi duplicate'
  622. ; swritef(M1, '\n%w sunt in plus,\n%w lipsesc', [TooMuch, TooLittle])
  623. ),
  624. swritef(M,
  625. 'Interogarea %w %w %w dar se astepta %w (%w)',
  626. [Text, TypeText, SetG, SetE, M1]), failure(Ex, M)
  627. ).
  628.  
  629. testSetMinus(From, ToRemove, Result) :-
  630. findall(E, (member(E, From), \+ member(E, ToRemove)), Result).
  631.  
  632. getVal(Var, [Var=Val | _], Val) :- !.
  633. getVal(Var, [_ | Vars], Val) :- getVal(Var, Vars, Val).
  634.  
  635. check :-
  636. clean,
  637. forall(exercitiul(Ex, _),
  638. ( atom_concat(check, Ex, Ck),
  639. retractall(current(_)), assert(current(Ex)),
  640. once(call(Ck)) ; true)),
  641. findall(P, punct(_, P), L),
  642. sum_list(L, S),
  643. format('Punctaj total: ~f~n',[S]),
  644. clean.
  645.  
  646. vmtest :- checkVm.
  647. checkVm :-
  648. clean,
  649. findall(T:Score, (tt(T, _), vmtest(T, Score)), Results),
  650. findall(Score, member(_:Score, Results), Scores),
  651. sum_list(Scores, S),
  652. format('Total: ~w~n', [S]),
  653. clean.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement