a(F,Term) :- clause(a Term,_), functor(Term,F,_), a Term.
an(F,Term) :- a(F,Term).

a emp(name     : thing
     ,dob      : a date
     ,shoesize : shoesize).

a date(day=D
      ,month=M : month
      ,year =Y : year) :-
	day(D,M,Y).

shoeSize(S) :- any(S,1,20).
year(Y)     :- any(S,1970,2020).
month(M)    :- any(M,1,12).

day(D,M,Y) :-
	year(D),
	month(M),
	(leapyearp(Y) -> leapday(D,M) ;  dullday(D,M)).

leapyearp(Y) :-
	0 is D mod 4,
	(0 is D mod 100 -> 0 is D mod 400; true).
	
leapday(D,2) :- any(D,1,29).
leapday(D,M) :- dullday(D,M).

dullday(D,2) :- any(D,1,28).
dullday(D,M) :- any(M,[9,4,6,11]),       any(D,1,30).
dullday(D,M) :- any(M,[1,3,5,7,8,10,12), any(D,1,31).

thing(X) :- var(X) -> gensym(any,X); true.
