module puzzle (grid) is process MAIN [PLACE:any, PRINT:any] (in var Month:Nat, in var Day:Nat) is var Crt_Grid:Grid, Pieces:Piece_List, Crt_Piece:Piece, Crt_Config:Config, Fits:Bool, J, Line, Coln:Nat, G_Line:Grid_Line, G_Array:Grid_Array in if (Month == 0) and (Day == 0) then -- Particular case of the current day Month := Get_Current_Month (); Day := Get_Current_Day () else assert (Month >= 1) and (Month <= 12) and (Day >= 1) and (Day <= 31) end if; Crt_Grid := Initial_Grid; -- Set the grid cells of the desired month and day as occupied eval Get_Month_Coordinates (Month, ?Line, ?Coln); -- Crt_Grid.A[Line][Coln] := X; G_Line := Crt_Grid.A [Line]; G_Line [Coln] := X; G_Array := Crt_Grid.A; G_Array [Line] := G_Line; Crt_Grid := Crt_Grid.{A -> G_Array}; eval Get_Day_Coordinates (Day, ?Line, ?Coln); -- Crt_Grid.A[Line][Coln] := Y; G_Line := Crt_Grid.A [Line]; G_Line [Coln] := Y; G_Array := Crt_Grid.A; G_Array [Line] := G_Line; Crt_Grid := Crt_Grid.{A -> G_Array}; Pieces := Puzzle_Pieces; -- Enumerate all pieces and attempt to place them on the grid while Pieces != nil loop L in Crt_Piece := head (Pieces); -- Choose a piece configuration and a grid cell to place it J := any Nat where J < Crt_Piece.Q; J := J + 1; Line := any Nat where Line < Crt_Grid.M; Line := Line + 1; Coln := any Nat where Coln < Crt_Grid.N; Coln := Coln + 1; Crt_Config := Get_Config (Crt_Piece, J); -- Attempt to place the piece configuration Fits := Check_Placement (Crt_Grid, Crt_Config, Line, Coln); if Fits then -- Successful placement: emit event and update the grid PLACE (Crt_Piece.P, Line, Coln, Crt_Config); Crt_Grid := Update_Grid (Crt_Grid, Crt_Piece.P, Line, Coln, Crt_Config); if Valid_Grid (Free_Cells (Crt_Grid)) then -- The updated grid may be valid for placing -- the remaining pieces Pieces := tail (Pieces) else -- The updated grid is certainly not valid for placing -- the remaining pieces: -- discard the current grid configuration break L end if else -- The current piece cannot be correctly placed: -- discard the current grid configuration break L end if end loop; if Pieces == nil then -- All pieces have been successfully placed: -- emit the solution event PRINT (Crt_Grid) end if end var end process end module